boringBob
boringBob

Reputation: 3

Android update ui elements from other class

I have a question about android programming. I have a MainActivity class and class that implements LocationListner. I want to change some UI elements from onLocationChanged method from this second class but I have no idea how things like this should be done.

Here is my mainActivity:

public class MainActivity extends AppCompatActivity {

private LocationGPS gps;
private TextView text;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    enableGPS();
    initGuiElements();
}

private void enableGPS()
{
    gps = new LocationGPS(this);
}

private void initGuiElements()
{
    text = (TextView) findViewById(R.id.textTop);
    text.setText("nothing yet");
}

}

Here is my class for location.

public class LocationGPS implements LocationListener {

private Activity mainActivity;
private LocationManager locationManager;

public LocationGPS(Activity activity)
{
    this.mainActivity = activity;
    locationManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE);
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}

@Override
public void onLocationChanged(Location location) {
    //here I want to set text for TextView element
}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {

}

@Override
public void onProviderEnabled(String provider) {

}

@Override
public void onProviderDisabled(String provider) {

}

}

Upvotes: 0

Views: 1485

Answers (5)

Ben
Ben

Reputation: 185

I found Artyom Okun's second code suggestion to be most helpful, however it did require some debugging. I had to move the interface to a file of its own. This was due to "Cyclical inheritance" where you try to inherit an object that you want to create within your activity.

See this stackoverflow page explaining the issue

MainActivity.java

public class MainActivity extends AppCompatActivity implements
    MainActivityInteractionInterface{

private LocationGPS gps;

private TextView text;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    enableGPS();
    initGuiElements();
}

private void enableGPS() {
    gps = new LocationGPS(this, getApplicationContext());
}

private void initGuiElements() {
    text = (TextView) findViewById(R.id.textTop);
    text.setText("nothing yet");
}

@Override
public void updateUI() {
   text.setText("Some new text");
}


}

LocationGPS.java

public class LocationGPS implements LocationListener{

    private MainActivityInteractionInterface interactionInterface;

    private LocationManager locationManager;

    private Context applicationContext;

    public LocationGPS(MainActivityInteractionInterface interactionInterface, Context applicationContext) {
        this.interactionInterface = interactionInterface;
        this.applicationContext = applicationContext;
        locationManager = (LocationManager) applicationContext.getSystemService(Context.LOCATION_SERVICE);
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
    }

    @Override
    public void onLocationChanged(Location location) {
        interactionInterface.updateUI(); // Or call this method whenever you need 
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }
    }

Then the new file MainActivityInteractionInterface.java

public interface MainActivityInteractionInterface {
    void updateUI();
}

To update the UI i update a global variable in the onLocationChanged() method of the LocationGPS class. then in updateUI() i use the global variable to write to text view.

note to write to the global in MainActivity its something like this:

MainActivity.bestLat = Lat;

Upvotes: 1

Nanoid
Nanoid

Reputation: 21

This is help you

public class LocationGPS implements LocationListener {

private Activity mainActivity;
private LocationManager locationManager;

public interface OnChangeListener{
 public void onChangeListener();

}

OnChangeListener mOnChangeListener;

public LocationGPS(Activity activity,OnChangeListener onChangeListener)
{
    this.mainActivity = activity;
  mOnChangeListener = onChangeListener;
  locationManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE);
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
}

@Override
public void onLocationChanged(Location location) {

//here I want to set text for TextView element
 mOnChangeListener.onChangeListener();   

}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {

}

@Override
public void onProviderEnabled(String provider) {

}

@Override
public void onProviderDisabled(String provider) {

}

Activity must implement interface OnChangeListener

public class MainActivity extends AppCompatActivity implements OnChangeListener {

private LocationGPS gps;
private TextView text;

@Override
 public void onChangeListener(){
//For example you may edit TextView
text.setText("data recieved:onLocationChanged")
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    enableGPS();
    initGuiElements();
}

private void enableGPS()
{

//You transfer interface
  gps = new LocationGPS(this,this);
}

private void initGuiElements()
{
    text = (TextView) findViewById(R.id.textTop);
    text.setText("nothing yet");
}

Upvotes: 0

Artyom Okun
Artyom Okun

Reputation: 985

You have bunch of ways to do this, I will give 2 of them:

  1. Change your activity to implement the LocationListener and when you call for locationManager.requestLocationUpdates pass the activity as the listener, that way you will get the callbacks called in the Activity and not in the LocationGPS class, the MainActivity will look like:

    public class MainActivity extends AppCompatActivity
        implements LocationListener {
    
    private LocationGPS gps;
    
    private TextView text;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        enableGPS();
        initGuiElements();
    }
    
    private void enableGPS() {
        gps = new LocationGPS(this);
    }
    
    private void initGuiElements() {
        text = (TextView) findViewById(R.id.textTop);
        text.setText("nothing yet");
    }
    
    @Override
    public void onLocationChanged(Location location) {
    
    }
    
    @Override
    public void onStatusChanged(String provider, int status,          
    Bundle extras) {
    
    }
    
    @Override
    public void onProviderEnabled(String provider) {
    
    }
    
    @Override
    public void onProviderDisabled(String provider) {
    
    }
    }
    

    And the LocationGPS class:

    public class LocationGPS {
    
    private Activity mainActivity;
    
    private LocationManager locationManager;
    
    public LocationGPS(Activity activity) {
        this.mainActivity = activity;
        locationManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE);
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mainActivity);
    }
    }
    
  2. The second way you can create a communication interface in MainActivty which you need to pass to LocationGPS class and once you want to update the UI in activity you call this interface method in next way:

    public class MainActivity extends AppCompatActivity implements
        MainActivity.MainActivityInteractionInterface{
    
    private LocationGPS gps;
    
    private TextView text;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        enableGPS();
        initGuiElements();
    }
    
    private void enableGPS() {
        gps = new LocationGPS(this, getApplicationContext());
    }
    
    private void initGuiElements() {
        text = (TextView) findViewById(R.id.textTop);
        text.setText("nothing yet");
    }
    
    @Override
    public void updateUI() {
       text.setText("Some new text");
    }
    
    public interface MainActivityInteractionInterface {
        void updateUI();
    }
    }
    

And the LocationGPS will look now like:

    public class LocationGPS implements LocationListener{

    private MainActivity.MainActivityInteractionInterface interactionInterface;

    private LocationManager locationManager;

    private Context applicationContext;

    public LocationGPS(MainActivity.MainActivityInteractionInterface interactionInterface, Context applicationContext) {
        this.interactionInterface = interactionInterface;
        this.applicationContext = applicationContext;
        locationManager = (LocationManager) applicationContext.getSystemService(Context.LOCATION_SERVICE);
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
    }

    @Override
    public void onLocationChanged(Location location) {
        interactionInterface.updateUI(); // Or call this method whenever you need 
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }
    }

Upvotes: 1

Abhishek Meher
Abhishek Meher

Reputation: 64

Just put the LocationGps class inside the MainActivity class. Done. Sorry not able to comment so posting as answer.

Upvotes: 0

Malwinder Singh
Malwinder Singh

Reputation: 7050

Create a method in your MainActivity

public void updateText(String updatedText){
 text.setText(updatedText);
}

In you LocationGPS class, you already have the context of MainActivity, so in onLocationChanged, call this method

mainActivity.updateText(updatedText);

There is another way which recommend personally. Create an interface and call it in the onLocationChanged method. Implement in your MainActivity and in the implemented interface update your text. I prefer this method as you will not need to share context or rootview of your Activity which prevents possible memory leaks.

Upvotes: 0

Related Questions