Java 试图从其父方法访问片段的接口

Java 试图从其父方法访问片段的接口,java,android,google-maps,android-fragments,Java,Android,Google Maps,Android Fragments,与谷歌的My Tracks应用程序的工作原理类似,我有一个地图片段选项卡和一个统计选项卡。因此,我需要从父活动访问LocationListener等方法。用户的路线将记录在父活动布局中的按键上。 如何从主活动中的方法访问这两个片段,以执行诸如更新地图的UI以跟踪用户以及使用运行统计数据(如用户的行驶距离)更新统计数据片段之类的操作 NewRouteActivity.java 活动\u new\u route.xml fragment_map.xml 您试图将数据从一个片段传递到另一个片段,但An

与谷歌的My Tracks应用程序的工作原理类似,我有一个地图片段选项卡和一个统计选项卡。因此,我需要从父活动访问LocationListener等方法。用户的路线将记录在父活动布局中的按键上。 如何从主活动中的方法访问这两个片段,以执行诸如更新地图的UI以跟踪用户以及使用运行统计数据(如用户的行驶距离)更新统计数据片段之类的操作

NewRouteActivity.java

活动\u new\u route.xml

fragment_map.xml


您试图将数据从一个片段传递到另一个片段,但Android中的片段间通信是通过接口进行的。其中必须有三个独立的活动主活动FragmentActivity1和FragmentActivity2。有关编码规范,请阅读。也来看看

代码中没有问题,只是没有遵循正确的数据交互顺序。还有viewpager&这将使您更好地了解如何为片段创建单独的活动以及片段之间的通信

public class NewRouteActivity extends FragmentActivity implements
        ConnectionCallbacks, OnConnectionFailedListener, LocationListener {

    /**
     * The {@link android.support.v4.view.PagerAdapter} that will provide
     * fragments for each of the sections. We use a
     * {@link 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}.
     */
    SectionsPagerAdapter mSectionsPagerAdapter;

    /**
     * The {@link ViewPager} that will host the section contents.
     */
    ViewPager mViewPager;

    public static FragmentManager fragmentManager;

    /**
     * JSONParser that will parse data to send to server
     */
    JSONParser jsonParser = new JSONParser();
    Gson gson = new Gson();

    /**
     * Static Variables
     */
    protected static final String TAG_CONTEXT = "NewRouteActivity";
    protected static final String TAG_DIALOG_SAVE_ROUTE = "Do you wish to save this route?";
    protected static final String TAG_DIALOG_YES = "OK";
    protected static final String TAG_DIALOG_NO = "No thanks";

    // Desired interval for location updates
    public static final long UPDATE_INTERVAL_MS = 1000;
    // Fastest rate for location updates
    public static final long FASTEST_UPDATE_INTERVAL_MS = UPDATE_INTERVAL_MS / 2;


    // Google Map
    protected GoogleMap mMap;
    // Entry point to Play Services
    protected GoogleApiClient mGoogleApiClient;
    // Stores parameters for requests to FusedLocationProviderApi
    protected LocationRequest mLocationRequest;
    // Represents a Geographical location
    protected Location mLocation;
    protected double mLatitude; // current latitude
    protected double mLongitude; // current longitude
    // Tracks status of location updates request
    protected Boolean mRequestingLocationUpdates;
    // Tracks whether route should be recorded or not
    protected Boolean mRecordRoute;

    // Stores user's geographical points
    protected List<LatLng> mLatLngs = new ArrayList<>();
    // Displays user's geographical points
    protected Polyline line;

    // Tracks distance covered
    protected float mDistance;
    protected float mTotalDistance;

    // Tracks time elapsed
    protected Long mStartTime; // (milliseconds)
    protected Long mEndTime;
    protected Long mTimeDifference;

    // Calendar to track date created
    protected static Calendar mCalendar = Calendar.getInstance();

    /**
     * User Model properties (as needed)
     */
    protected User user = new User();
    protected int mId;

    /**
     * Route Model Properties
     */
    protected Grade routeGrade;
    protected Terrain routeTerrain;
    protected List<Double> routeLats = new ArrayList<>();
    protected List<Double> routeLngs = new ArrayList<>();
    protected float routeDistance;
    protected Date dateCreated;

    /**
     * Results Model Properties
     */
    protected int routeId;
    protected int mExperience;
    protected float mMaxSpeed;
    // protected float routeDistance;
    protected float avgSpeed;
    protected Date mTime;
    // protected Date dateCreated;

    /**
     * UI Widgets
     */
    // Buttons
    protected ImageView mButtonRecord;
    protected ImageView mButtonPause;
    protected ImageView mButtonStop;
    // TextViews


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_new_route);
        final ActionBar actionBar = getActionBar();
        actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        actionBar.setDisplayShowHomeEnabled(false);
        actionBar.setDisplayShowTitleEnabled(false);
        fragmentManager = getSupportFragmentManager();

        // Locate UI Widgets
        mButtonRecord = (ImageView) findViewById(R.id.btnRecord);
        mButtonStop = (ImageView) findViewById(R.id.btnStop);

        // Set Location Updates status to false
        mRequestingLocationUpdates = false;
        mRecordRoute = false;
        mTotalDistance = 0;

        // Create the adapter that will return a fragment for each of the three
        // primary sections of the activity.
        mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());

        // Set up the ViewPager with the sections adapter.
        mViewPager = (ViewPager) findViewById(R.id.pager);
        mViewPager.setAdapter(mSectionsPagerAdapter);

        // Create a tab listener that is called when the user changes tabs.
        ActionBar.TabListener tabListener = new ActionBar.TabListener() {

            @Override
            public void onTabSelected(ActionBar.Tab tab, android.app.FragmentTransaction ft) {
                mViewPager.setCurrentItem(tab.getPosition());
            }

            @Override
            public void onTabUnselected(ActionBar.Tab tab, android.app.FragmentTransaction ft) {

            }

            @Override
            public void onTabReselected(ActionBar.Tab tab, android.app.FragmentTransaction ft) {

            }
        };

        mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                getActionBar().setSelectedNavigationItem(position);
            }
        });

        // Add 2 tabs
        for(int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
            actionBar.addTab(actionBar
                    .newTab()
                    .setText(mSectionsPagerAdapter.getPageTitle(i))
                    .setTabListener(tabListener));
        }

        // Create Listeners for Record/Stop buttons
        mButtonRecord.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.i(TAG_CONTEXT, "Start Recording...");
                mStartTime = System.currentTimeMillis(); // start timer
                startUpdatesButtonHandler();
            }
        });
        mButtonStop.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.i(TAG_CONTEXT, "Stop recording.");
                mEndTime = System.currentTimeMillis(); // end timer
                stopUpdatesButtonHandler();
            }
        });

        buildGoogleApiClient();

    }


    /**
     * Build entry point params for Play Services
     */
    protected synchronized void buildGoogleApiClient() {
        Log.i(TAG_CONTEXT, "Building GoogleApiClient...");
        mGoogleApiClient = new Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
        createLocationRequest();
    }

    /**
     * Sets up location request boundaries
     */
    private void createLocationRequest() {
        mLocationRequest = new LocationRequest();

        // Sets desired interval for active location updates
        mLocationRequest.setInterval(UPDATE_INTERVAL_MS);

        // Sets fastest interval for location updates
        mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_MS);

        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }

    /**
     * Handles the Start Updates button and requests start of location updates. Does nothing if
     * updates have already been requested.
     */
    private void startUpdatesButtonHandler() {
        if(!mRequestingLocationUpdates) {
            mRequestingLocationUpdates = true;
            setButtonsEnabledState();
            startLocationUpdates();
        }
    }

    /**
     * Handles the Stop Updates button, and requests removal of location updates. Does nothing if
     * updates were not previously requested.
     */
    public void stopUpdatesButtonHandler() {
        if (mRequestingLocationUpdates) {
            mRequestingLocationUpdates = false;
            setButtonsEnabledState();
            stopLocationUpdates();
        }
    }

    private void setButtonsEnabledState() {
        if (mRequestingLocationUpdates) {
            mButtonRecord.setEnabled(false);
            mButtonStop.setEnabled(true);
        } else {
            mButtonRecord.setEnabled(true);
            mButtonStop.setEnabled(false);
        }
    }

    /**
     * Removes location updates from the FusedLocationApi
     */
    private void stopLocationUpdates() {
        LocationServices.FusedLocationApi.
                removeLocationUpdates(mGoogleApiClient, this);
    }

    /**
     * Requests location updates from FusedLocationApi
     */
    protected void startLocationUpdates() {
        LocationServices.FusedLocationApi.requestLocationUpdates(
                mGoogleApiClient, mLocationRequest, this
        );
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_new_route, 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;
        }

        return super.onOptionsItemSelected(item);
    }

    @Override
    protected void onStart() {
        super.onStart();
        mGoogleApiClient.connect();
    }

    @Override
    protected void onResume() {
        super.onResume();

        if(mGoogleApiClient.isConnected() && mRequestingLocationUpdates) {
            startLocationUpdates();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        // Stop location updates but don't disconnect the GoogleApiClient
        // stopLocationUpdates();
    }

    @Override
    protected void onStop() {
        super.onStop();
        /*
        if(mGoogleApiClient.isConnected()) {
            mGoogleApiClient.disconnect();
        }
        */
    }

    @Override
    public void onConnected(Bundle bundle) {
        Log.i(TAG_CONTEXT, "Connected to GoogleApiClient");

        if(mLocation == null) {
            mLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        }

        // If user presses Start button before GoogleApiClient connects
        // set mRequestingLocationUpdates to true
        if(mRequestingLocationUpdates) {
            startLocationUpdates();
        }
    }

    @Override
    public void onConnectionSuspended(int i) {
        // Connection to Play Services lost
        // Try to re-connect
        Log.i(TAG_CONTEXT, "Connection Suspended");
        mGoogleApiClient.connect();
    }

    @Override
    public void onLocationChanged(Location location) {
        mLocation = location;
        mLatitude = location.getLatitude();
        mLongitude = location.getLongitude();
        trackDistance();
        // trackSpeed();
        saveLocation();
        updateUI();
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        stopLocationUpdates();
        Log.i(TAG_CONTEXT, "Connection failed: ConnectionResult.getErrorCode() = "
                + connectionResult.getErrorCode());
    }


    /**
     * Track total distance covered
     */
    private void trackDistance() {
        if(!mLatLngs.isEmpty()) {
            Location lastLocation = new Location("LastLocation");
            double x = mLatLngs.get(mLatLngs.size()-1).latitude; // previous latitude point in array
            double y = mLatLngs.get(mLatLngs.size()-1).longitude; // previous longitude point in array

            // set previous location parameters
            lastLocation.setLatitude(x);
            lastLocation.setLongitude(y);

            if(mLocation != lastLocation) {
                // find distance between two neighbouring points
                // add to total distance
                mDistance = lastLocation.distanceTo(mLocation); // metres
                mTotalDistance += mDistance; // total metres
                Log.i(TAG_CONTEXT, "Distance (m): " + mTotalDistance);
            }

        }
    }

    /**
     * Save location to array
     */
    private void saveLocation() {
        LatLng latLong = new LatLng(mLatitude, mLongitude);
        // save points to array
        Log.i(TAG_CONTEXT, "Saving points: " + latLong);
        mLatLngs.add(new LatLng(mLatitude, mLongitude));
        routeLats.add(mLatitude);
        routeLngs.add(mLongitude);
    }

    /**
     * Update UI in real-time
     * Follow User as they move
     * Show distance covered
     */
    private void updateUI() {
        LatLng latLng = new LatLng(mLatitude, mLongitude);
        // plot points on UI
        line = mMap.addPolyline(new PolylineOptions()
                .add(latLng)
                .width(6f)
                .color(Color.BLUE)
                .geodesic(true));

        // move camera to updated position on map
        CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 16);
        mMap.animateCamera(cameraUpdate);

        /*
        if(mTotalDistance < 1000) {
            // display in metres
            mTextDistance.setText(String.format("%.1f (m)", mTotalDistance));
        }
        else {
            // display in kilometres
            mTextDistance.setText(String.format("%.2f (km)", mTotalDistance/1000));
        }
        */
    }


    /**
     * A {@link FragmentPagerAdapter} that returns a fragment corresponding to
     * one of the sections/tabs/pages.
     */
    public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
        public SectionsPagerAdapter(FragmentManager fm) {
            super(fm);
        }

        @Override
        public Fragment getItem(int position) {
            // getItem is called to instantiate the fragment for the given page.
            // Return a PlaceholderFragment (defined as a static inner class below).
            switch (position) {
                case 0:
                    Fragment fragment = new MyMapFragment();
                    Bundle args = new Bundle();
                    fragment.setArguments(args);
                    return fragment;
                case 1:
                    return new StatisticsFragment();
            }
            return null;
        }

        @Override
        public int getCount() {
            // Show 2 total pages.
            return 2;
        }

        @Override
        public CharSequence getPageTitle(int position) {
            Locale l = Locale.getDefault();
            switch (position) {
                default:
                    return getString(R.string.title_map).toUpperCase(l);
                case 1:
                    return getString(R.string.title_statistics).toUpperCase(l);
            }
        }
    }

    /**
     * A placeholder fragment containing map view.
     */
    public static class MyMapFragment extends Fragment {

        private GoogleMap mMap;

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            initMap();
        }

        @Override
        public View onCreateView(LayoutInflater inflater,
                                 ViewGroup container, Bundle savedInstanceState) {
            // The last two arguments ensure LayoutParams are inflated
            // properly.
            View rootView = inflater.inflate(
                    R.layout.fragment_map, container, false);
            // Bundle args = getArguments();

            return rootView;
        }

        private GoogleMap initMap() {
            if(mMap == null && getActivity() != null
                    && getActivity().getSupportFragmentManager() != null) {
                SupportMapFragment smf = (SupportMapFragment)getActivity().
                        getSupportFragmentManager().findFragmentById(R.id.map);
                if(smf != null) {
                    mMap = smf.getMap();
                    mMap.setMyLocationEnabled(true);
                }
            }
            return mMap;
        }

        @Override
        public void onDestroyView() {
            super.onDestroyView();
        }
    }

    public static class StatisticsFragment extends Fragment {
        // public static final String ARG_OBJECT = "object";

        @Override
        public View onCreateView(LayoutInflater inflater,
                                 ViewGroup container, Bundle savedInstanceState) {
            // The last two arguments ensure LayoutParams are inflated
            // properly.
            View rootView = inflater.inflate(
                    R.layout.fragment_statistics, container, false);
            // Bundle args = getArguments();
            /*((TextView) rootView.findViewById(android.R.id.text1)).setText(
                    Integer.toString(args.getInt(ARG_OBJECT)));*/
            return rootView;
        }
    }
}
<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:layout_centerHorizontal="true"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools" android:id="@+id/pager"
        android:layout_width="match_parent" android:layout_height="450dip"
        tools:context="apex.prj300.ie.apex.app.NewRouteActivity"
        android:layout_above="@+id/buttons" />

    <LinearLayout
        android:background="@color/apex_black"
        android:id="@+id/buttons"
        android:layout_width="fill_parent"
        android:layout_height="130dip"
        android:gravity="center"
        android:orientation="horizontal"
        android:layout_centerHorizontal="true"
        android:layout_alignParentBottom="true">

    <ImageView
        android:background="@null"
        android:id="@+id/btnRecord"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_margin="0dip"
        android:src="@drawable/button_record" />

    <TextView
        android:layout_width="30dip"
        android:layout_height="match_parent" />

    <ImageView
        android:background="@null"
        android:id="@+id/btnStop"
        android:layout_width="100dip"
        android:layout_height="100dip"
        android:layout_margin="4dip"
        android:src="@drawable/button_stop" />

    </LinearLayout>

</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<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="340dp" android:id="@+id/map"
    tools:context="apex.prj300.ie.apex.app.RecordActivity"
    android:name="com.google.android.gms.maps.SupportMapFragment" />