Current Location button is not showing - google-maps

I am using google map V2 in android app by tab(viewPager) and I want to show current location in map but I couldn't find this button.
AddMasjid.java
package com.example.saroosh.masjidnow.Tabs;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.saroosh.masjidnow.R;
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.MapView;
import com.google.android.gms.maps.MapsInitializer;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
public class AddMasjid extends Fragment implements OnMapReadyCallback{
MapView gMapView;
GoogleMap gMap = null;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v =inflater.inflate(R.layout.add_masjid,container,false);
gMapView = (MapView) v.findViewById(R.id.map);
gMapView.getMapAsync(this);
gMapView.onCreate(savedInstanceState);
gMapView.onResume(); // needed to get the map to display immediately
try {
MapsInitializer.initialize(getActivity().getApplicationContext());
} catch (Exception e) {
e.printStackTrace();
}
return v;
}
#Override
public void onMapReady(GoogleMap map) {
gMap = map;
gMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
gMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new
LatLng(0, 0), 0));
if (gMap != null) {
gMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
gMap.getUiSettings().setMyLocationButtonEnabled(true); }
}
#Override
public void onResume() {
super.onResume();
gMapView.onResume();
}
#Override
public void onPause() {
super.onPause();
gMapView.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
gMapView.onDestroy();
}
#Override
public void onLowMemory() {
super.onLowMemory();
gMapView.onLowMemory();
}
}
add_masjid.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#000000">
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/editText1"
android:layout_alignBottom="#+id/editText1"
android:layout_alignParentStart="true"
android:text="#string/xyz"
android:textColor="#FFFFFF"
android:textSize="20sp"
/>
<Button
android:id="#+id/generalId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:background="#drawable/rect1"
android:onClick="geoLocate"
android:text="#string/abc"
android:textColor="#FFFFFF"
android:textSize="20sp" />
<EditText
android:id="#+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="#+id/textView1"
android:layout_toStartOf="#+id/generalId"
android:ems="10"
android:inputType="text"
android:background="#FFFFFF"
android:labelFor="#+id/editText1"
android:layout_above="#+id/map"
android:layout_alignParentTop="true" />
<com.google.android.gms.maps.MapView
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/generalId">
</com.google.android.gms.maps.MapView>
<!--<fragment-->
<!--android:id="#+id/map"-->
<!--android:name="com.google.android.gms.maps.SupportMapFragment"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content"-->
<!--android:layout_alignParentBottom="true"-->
<!--android:layout_below="#+id/generalId" />-->
</RelativeLayout>
Please anybody guide me how can I get this button in my app.

I have solved my problem by adding some code in it, like this.
#Override
public void onMapReady(GoogleMap map) {
gMap = map;
gMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
gMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new
LatLng(0, 0), 0));
if (gMap != null) {
gMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
if (ActivityCompat.checkSelfPermission(getActivity().getApplicationContext()
, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getActivity().getApplicationContext()
, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
gMap.setMyLocationEnabled(true);
gMap.getUiSettings().setMyLocationButtonEnabled(true);
}
}

Here are some nice tutorials to get current location
Link
Link
Learn to get current location from here than update the location parameters lat n lng in this code like this.
public void onMapReady(GoogleMap map) {
gMap = map;
gMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
gMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new
LatLng(lat, lng), 0));
if (gMap != null) {
gMap.addMarker(new MarkerOptions().position(new LatLng(lat, lng)).title("Marker"));
gMap.getUiSettings().setMyLocationButtonEnabled(true); }
}

Related

How to dynamically add MvxFrameControl in MvvmCross Android

I need to dynamically create MvxFrameControll, inflate it with content and add to another Layout (FrameLayout / LinearLayout).
My code is
HomeScreen.axml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<krista.fm.iMonitoring.Android.Native.TopBar
android:layout_width="match_parent"
android:layout_height="50dp"
local:MvxBind="DataContext TopBar"
local:MvxTemplate="#layout/topbar"
android:id="#+id/TopBar" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/SubjectBodyContainer" />
</LinearLayout>
public class SubjectBody : MvxFrameControl
{
public SubjectBody (Context context, IAttributeSet attrs) : base (context, attrs)
{
}
public SubjectBody (int templateId, Context context, IAttributeSet attrs) : base (context, attrs)
{
}
protected override void OnContentSet ()
{
base.OnContentSet ();
}
}
HomeScreenView
[Activity (Label = "HomeScreen")]
public class HomeScreenView : MvxActivity
{
public override void OnAttachedToWindow()
{
base.OnAttachedToWindow();
}
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
SetContentView (Resource.Layout.HomeScreen);
AddSubjectBody();
}
protected override void OnStart()
{
base.OnStart();
}
protected virtual void AddSubjectBody()
{
var container = FindViewById<FrameLayout>(Resource.Id.SubjectBodyContainer);
var subjectBody = new SubjectBody(Resource.Layout.SubjectBody, this, null);
subjectBody.DataContext = new SubjectBodyViewModel();
container.AddView(subjectBody, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent));
}
}
Why this code doesn't add content on screen and how it rewrite rightly? When I use SubjectBody adding inside axml with templateId it works correctly. But what if i need adding this dynamically?
protected virtual void AddSubjectBody()
{
var container = FindViewById<FrameLayout>(Resource.Id.SubjectBodyContainer);
var subjectBody = new SubjectBody(Resource.Layout.SubjectBody, this, null);
subjectBody.DataContext = new SubjectBodyViewModel();
container.AddView(subjectBody, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MatchParent, ViewGroup.LayoutParams.MatchParent));
}
Are you sure your code is running on the UI thread? I'm using pretty a similar code in one app and the view gets added into the parent. What I suggest you to try is:
this.RunOnUiThread(() => container.AddView(this.subjectBody));

Fail to get permission to get current longitude and latitude

I am trying to make my program able to get the user's current longitude and latitude and then place a marker to it. I have used various method in the Internet but none of them seemed to work. From what I have observed I suspect the reason the trouble is that the program fails to get the permission, despite I have already set it in the manifest
Here is the code, I currently only use setMyLocationEnabled to demonstrate the problem
package com.example.user.googlemaptest2;
import android.*;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationManager;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;
import com.google.android.gms.location.LocationListener;
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;
import java.io.IOException;
import java.util.List;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
private double longitudeDefaultLocation;
private double latitudeDefaultLocation;
private static final int MY_PERMISSION_ACCESS_COARSE_LOCATION = 11;
private static final int MY_PERMISSION_ACCESS_FINE_LOCATION = 12;
private final LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
longitudeDefaultLocation = location.getLongitude();
latitudeDefaultLocation = location.getLatitude();
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions( this, new String[] { android.Manifest.permission.ACCESS_COARSE_LOCATION },
MapsActivity.MY_PERMISSION_ACCESS_COARSE_LOCATION );
ActivityCompat.requestPermissions( this, new String[] { Manifest.permission.ACCESS_FINE_LOCATION },
MapsActivity.MY_PERMISSION_ACCESS_FINE_LOCATION );
}
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
mMap.setMyLocationEnabled(true);
mMap.animateCamera(CameraUpdateFactory.zoomTo(14));
}
else
{
Toast.makeText(MapsActivity.this,"FAIL", Toast.LENGTH_LONG).show();
}
}
public void onSearch(View view)
{
EditText location_tf = (EditText)findViewById(R.id.TFaddress);
String location = location_tf.getText().toString();
List<Address> addressList = null;
if (location !=null || location.equals("")) {
Geocoder geocoder = new Geocoder(this);
try {
addressList = geocoder.getFromLocationName(location,1);
} catch (IOException e) {
e.printStackTrace();
}
Address address = addressList.get(0);
LatLng latLng = new LatLng( address.getLatitude(), address.getLongitude());
mMap.addMarker(new MarkerOptions().position(latLng).title("Marker"));
mMap.animateCamera(CameraUpdateFactory.newLatLng(latLng));
}
}
public void changeType (View view)
{
if (mMap.getMapType() == GoogleMap.MAP_TYPE_NORMAL)
{
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
}
else
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
}
public void onZoom(View view)
{
if (view.getId() == R.id.zoomInButton);
{
mMap.animateCamera(CameraUpdateFactory.zoomIn());
}
if (view.getId() == R.id.zoomOutButton)
{
mMap.animateCamera(CameraUpdateFactory.zoomOut());
}
}
This is the content of my Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.user.googlemaptest2">
<!--
The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
Google Maps Android API v2, but you must specify either coarse or fine
location permissions for the 'MyLocation' functionality.
-->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<!--
The API key for Google Maps-based APIs is defined as a string resource.
(See the file "res/values/google_maps_api.xml").
Note that the API key is linked to the encryption key used to sign the APK.
You need a different API key for each encryption key, including the release key that is used to
sign the APK for publishing.
You can define the keys for the debug and release targets in src/debug/ and src/release/.
-->
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="My Key is Here" />
<activity
android:name=".MapsActivity"
android:label="#string/title_activity_maps">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

call permission which may be rejected for setMyLocationEnable android

Alas! after a lots of efforts and search I couldn't find my problem. I want to find current location in google map but I am still getting an error(required permissions).
call requires permission which may be rejected by user: code should
explicitly check to see if permission is available (with check
permission) or explicitly handle a potential 'security Exception'
at gMap.setMyLocationEnable(true); Please anybody guide me how can I fix it? My code is given below.
AddMasjid.java
package com.example.saroosh.masjidnow.Tabs;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.saroosh.masjidnow.R;
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.MapView;
import com.google.android.gms.maps.MapsInitializer;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
public class AddMasjid extends Fragment implements OnMapReadyCallback{
MapView gMapView;
GoogleMap gMap = null;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v =inflater.inflate(R.layout.add_masjid,container,false);
gMapView = (MapView) v.findViewById(R.id.map);
gMapView.getMapAsync(this);
gMapView.onCreate(savedInstanceState);
gMapView.onResume(); // needed to get the map to display immediately
try {
MapsInitializer.initialize(getActivity().getApplicationContext());
} catch (Exception e) {
e.printStackTrace();
}
return v;
}
#Override
public void onMapReady(GoogleMap map) {
gMap = map;
gMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
gMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new
LatLng(0, 0), 0));
if (gMap != null) {
gMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
gMap.setMyLocationEnabled();
}
}
#Override
public void onResume() {
super.onResume();
gMapView.onResume();
}
#Override
public void onPause() {
super.onPause();
gMapView.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
gMapView.onDestroy();
}
#Override
public void onLowMemory() {
super.onLowMemory();
gMapView.onLowMemory();
}
}
add_masjid.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#000000">
<TextView
android:id="#+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="#+id/editText1"
android:layout_alignBottom="#+id/editText1"
android:layout_alignParentStart="true"
android:text="#string/xyz"
android:textColor="#FFFFFF"
android:textSize="20sp"
/>
<Button
android:id="#+id/generalId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:background="#drawable/rect1"
android:onClick="geoLocate"
android:text="#string/abc"
android:textColor="#FFFFFF"
android:textSize="20sp" />
<EditText
android:id="#+id/editText1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="#+id/textView1"
android:layout_toStartOf="#+id/generalId"
android:ems="10"
android:inputType="text"
android:background="#FFFFFF"
android:labelFor="#+id/editText1"
android:layout_above="#+id/map"
android:layout_alignParentTop="true" />
<com.google.android.gms.maps.MapView
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/generalId">
</com.google.android.gms.maps.MapView>
</RelativeLayout>
I have just solved my problem by adding some permissions in it.
#Override
public void onMapReady(GoogleMap map) {
gMap = map;
gMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
gMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new
LatLng(0, 0), 0));
//add this code...
if (gMap != null) {
gMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
if (ActivityCompat.checkSelfPermission(getActivity().getApplicationContext()
, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getActivity().getApplicationContext()
, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
gMap.setMyLocationEnabled(true);
gMap.getUiSettings().setMyLocationButtonEnabled(true);
}
}

JAVAFX TableView CELL should display text in multiline in single cell with multi color. possible?

I need to have TableView CELL should display text in multi line in single cell with multi color.
In CELL I am displaying Multiline text using "\n" currently. But I am not able to set color for each line in the same cell,
for example text in the CELL is : Charlotte , 403 St. Tryon Street then I want In Single cell, Charlotte as first line and 403 St. Tryon Street as sencond line with Charlotte as RED color and remaining text on 2nd line as Green color.
You can use a cellFactory to customize the way the content is displayed. Assuming the values for the column are Strings like "Charlotte\n403 St. Tryon Street" and "Tony Stark\n10880 Malibu Point\n90265"
It could be done like this:
column.setCellFactory(tv -> new TableCell<MyItemType, String>() {
private final VBox lines;
{
lines = new VBox();
lines.getStyleClass().add("address");
setGraphic(lines);
}
#Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
lines.getChildren().clear();
if (!empty && item != null) {
int lineNo = 1;
for (String line : item.split("\n")) {
Text text = new Text(line);
text.getStyleClass().add("line-" + (lineNo++));
lines.getChildren().add(text);
}
}
}
});
CSS stylesheet
.address > * {
-fx-fill: green;
}
.address > .line-1 {
-fx-fill: red;
}
Note that this uses CSS to style the lines, but you could also assign the color in the updateItem method directly...
You can use a custom cell factory in this case, here is an example:
I've created an FXML document that contains a TableView holding two TableColumns, one for the fullname and the second for the address of a Person instance.
I've then set the cellFactory as follows:
addressCol.setCellFactory(column->{
return new TableCell<Person, String>() {
#Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if(item==null || empty) {
setGraphic(null);
} else {
VBox vbox = new VBox();
List<String> textList = Arrays.asList(item.split("\n"));
String[] colors = {"#3E50B4", "#FF3F80", "#727272"};
int colorCount = colors.length;
for(int i=0;i<textList.size();i++) {
Label lbl = new Label(textList.get(i));
lbl.setStyle("-fx-text-fill: "+colors[i%colorCount]);
vbox.getChildren().add(lbl);
}
setGraphic(vbox);
}
}
};
});
Now this is just an example where I've used a VBox containing a bunch of Label instances (one for each line), and I've hard coded the colors, you can use whatever you like, for example, you can try a TextFlow with Text nodes and you can also use CSS Style classes.
Here is the full example code:
TableViewExample.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import javafx.geometry.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<VBox alignment="CENTER" spacing="10.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
<children>
<Label text="Colored Lines of Text in a Table Cell Example">
<font>
<Font size="16.0" />
</font>
</Label>
<TableView fx:id="personTable" prefHeight="200.0" prefWidth="200.0">
<columns>
<TableColumn fx:id="fullnameCol" prefWidth="75.0" text="Full Name" />
<TableColumn fx:id="addressCol" prefWidth="75.0" text="Address" />
</columns>
<columnResizePolicy>
<TableView fx:constant="CONSTRAINED_RESIZE_POLICY" />
</columnResizePolicy>
</TableView>
</children>
</VBox>
Person.java
public class Person {
private String fullname, address;
public Person() {}
public Person(String fullname, String address) {
this.fullname = fullname;
this.address = address;
}
public String getFullname() {
return fullname;
}
public void setFullname(String fullname) {
this.fullname = fullname;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
MainApp.java
import java.net.URL;
import java.util.Arrays;
import java.util.List;
import java.util.ResourceBundle;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class MainApp extends Application implements Initializable {
#FXML private TableView<Person> personTable;
#FXML private TableColumn<Person, String> fullnameCol, addressCol;
ObservableList<Person> persons = FXCollections.observableArrayList();
public static void main(String [] args) {
launch(args);
}
#Override
public void initialize(URL url, ResourceBundle rb) {
Person p1 = new Person("John Doe", "Charlotte ,\n403 St. Tryon Street");
Person p2 = new Person("Riyad Mahrez", "xxxxx, \n007 St.YYYY");
persons.addAll(p1, p2);
fullnameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("fullname"));
addressCol.setCellValueFactory(new PropertyValueFactory<Person, String>("address"));
addressCol.setCellFactory(column->{
return new TableCell<Person, String>() {
#Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if(item==null || empty) {
setGraphic(null);
} else {
VBox vbox = new VBox();
List<String> textList = Arrays.asList(item.split("\n"));
String[] colors = {"#3E50B4", "#FF3F80", "#727272"};
int colorCount = colors.length;
for(int i=0;i<textList.size();i++) {
Label lbl = new Label(textList.get(i));
lbl.setStyle("-fx-text-fill: "+colors[i%colorCount]);
vbox.getChildren().add(lbl);
}
setGraphic(vbox);
}
}
};
});
personTable.setItems(persons);
}
#Override
public void start(Stage primaryStage) throws Exception {
FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("TableViewExample.fxml"));
loader.setController(this);
Parent parent = loader.load();
Scene scene = new Scene(parent);
primaryStage.setScene(scene);
primaryStage.show();
}
}
I hope this helps...

Dynamically updating a ListView from JSON object using a custom ListViewAdapter

As usual the question comes from a first time user of Android. Its three weeks later and im tearing my hair out will do my best to explain the problem.
Firstly I am using Exlipse 3.7.1 and SDK r15 as of today because I thought Ill try upgrade maybe thats whats causing the issues but seems to be the same while using r13.
Here is a working copy of my code:
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="center_horizontal"
android:id="#+id/llMain"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:background="#drawable/header"
android:id="#+id/linearLayout1"
android:layout_height="50dp"
android:layout_width="fill_parent">
<ImageButton
android:background="#null"
android:id="#+id/ibHome"
android:layout_gravity="center_vertical"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight=".25"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:src="#drawable/trophy_cup" />
<ImageView
android:background="#000000"
android:id="#+id/imageView1"
android:layout_height="match_parent"
android:layout_width="1dp" />
<TextView
android:gravity="center_horizontal"
android:id="#+id/lblHome"
android:layout_height="50dp"
android:layout_width="0dp"
android:layout_weight="1"
android:paddingTop="14dp"
android:text="#string/helloHome"
android:textColor="#color/txtYellow"
android:textSize="18dp"
android:textStyle="bold"
android:typeface="serif" />
<ImageView
android:id="#+id/imageView2"
android:layout_height="match_parent" android:background="#000000"
android:layout_width="1dp" />
<ImageButton
android:background="#null"
android:focusable="true"
android:id="#+id/ibQuit"
android:layout_gravity="center_vertical"
android:layout_height="wrap_content"
android:layout_width="0dp"
android:layout_weight=".25"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:src="#drawable/yellow_flag" />
</LinearLayout>
<!-- Body code goes here -->
<LinearLayout
android:id="#+id/linearLayout2"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_weight="1"
android:gravity="center_horizontal" android:paddingTop="10dp">
<TextView
android:id="#+id/lblHeading"
android:layout_width="wrap_content"
android:layout_height="40dp"
android:layout_weight="0.17"
android:gravity="center_horizontal"
android:isScrollContainer="true"
android:text="Top"
android:textColor="#color/txtYellow"
android:textSize="22dp"
android:textStyle="bold" android:paddingTop="7dp" android:typeface="serif"/>
<Spinner
android:entries="#array/strArrTop"
android:id="#+id/spinTop"
android:layout_width="90dp"
android:layout_height="wrap_content"
android:layout_weight="0.44"
android:focusableInTouchMode="true"
android:longClickable="true"/>
</LinearLayout>
<LinearLayout
android:id="#+id/linearLayout3"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
android:gravity="center_horizontal"
android:padding="25dp"
android:orientation="vertical" >
<ListView
android:id="#+id/list1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:isScrollContainer="true" />
</LinearLayout>
<!-- End Body code goes here -->
<LinearLayout
android:id="#+id/linearLayout4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal" >
<TextView
android:id="#+id/lblWidth"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
<ImageView
android:layout_height="120dp"
android:layout_width="201dp"
android:scaleType="fitXY"
android:src="#drawable/ddo_logo" />
<TextView
android:id="#+id/lblHeight"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
</LinearLayout>
</LinearLayout>
mylist.xml (the custom list adapter)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_weight="1"
android:layout_height="wrap_content" android:gravity="left|center">
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal">
<TextView
android:id="#+id/txt1"
android:layout_width="182dp"
android:layout_height="wrap_content"
android:layout_weight="0.21"
android:textColor="#color/txtYellow" />
<TextView
android:id="#+id/txt2"
android:layout_width="40dp"
android:layout_height="wrap_content"
android:textColor="#color/txtYellow" />
</LinearLayout>
</LinearLayout>
The manifest file, uses minSDK 8.0
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.hunta.DDOFastestTimes"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<uses-permission android:name="android.permission.INTERNET"/>
<supports-screens
android:normalScreens="true"
android:largeScreens="true" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:label="#string/app_name"
android:name=".DDOFastestTimesActivity" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
and finally the offending java file:
package com.hunta.DDOFastestTimes;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.content.Context;
import android.net.ParseException;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
public class DDOFastestTimesActivity extends Activity implements OnClickListener {
/** JSON variables */
String jc1, jc2 = null;
/** END JSON variables */
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/** JSON variables */
String result = null;
InputStream is = null;
StringBuilder sb = null;
/** END JSON variables */
ImageButton closeApp = (ImageButton) findViewById(R.id.ibQuit);
closeApp.setOnClickListener(this);
/** http://www.dcpagesapps.com/developer-resources/android/21-android-tutorial-spinners?start=1 */
/** Populating the spinner from that string-array */
Spinner s = (Spinner) findViewById( R.id.spinTop );
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource( this, R.array.strArrTop, android.R.layout.simple_spinner_item );
adapter.setDropDownViewResource( android.R.layout.simple_spinner_dropdown_item );
/** END Populating the spinner from that string-array */
/** Create a reference to our spinner */
s.setAdapter( adapter );
/** END Create a reference to our spinner */
/** END http://www.dcpagesapps.com/developer-resources/android/21-android-tutorial-spinners?start=1 */
s.setOnItemSelectedListener(new MyOnItemSelectedListener());
/** JSON code to initiate the php */
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
//http post
try{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://url-to-my-php-file/fastag.php");
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
}catch(Exception e){
Log.e("log_tag", "Error in http connection"+e.toString());
}
//convert response to string
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
sb = new StringBuilder();
sb.append(reader.readLine() + "\n");
String line="0";
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result=sb.toString();
}catch(Exception e){
Log.e("log_tag", "Error converting result "+e.toString());
}
//paring data
JSONArray jArray;
try{
jArray = new JSONArray(result);
JSONObject json_data=null;
// Adding the JSON data to the list view
int length = jArray.length();
List<String> listContents1 = new ArrayList<String>(length);
List<String> listContents2 = new ArrayList<String>(length);
// Convert ListString Array to an ArrayList
ArrayList<tblRecord> arrTxt = new ArrayList<tblRecord>();
// Changing the ListViews
for(int i=0;i<jArray.length();i++){
json_data = jArray.getJSONObject(i);
jc1 = json_data.getString("c1");
jc2 = json_data.getString("c2");
listContents1.add(json_data.getString("c1"));
listContents2.add(json_data.getString("c2"));
// Create an Array to pass to our custom view
tblRecord addRecord = new tblRecord(jc1, jc2);
arrTxt.add(addRecord);
}
ListView myListView1 = (ListView) findViewById(R.id.list1);
myListView1.setAdapter(new UserItemAdapter(this, android.R.layout.simple_list_item_1, arrTxt));
// END Adding the JSON data to the list view
}
catch(JSONException e1){
Toast.makeText(getBaseContext(), "No Results Found" ,Toast.LENGTH_LONG).show();
} catch (ParseException e1) {
e1.printStackTrace();
}
/** END JSON code to initiate the php */
}
/** End Called when the activity is first created. */
/** Using a custom List View */
public class UserItemAdapter extends ArrayAdapter<tblRecord> {
private ArrayList<tblRecord> arrList;
public UserItemAdapter(Context context, int textViewResourceId, ArrayList<tblRecord> arrList) {
super(context, textViewResourceId, arrList);
this.arrList = arrList;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.mylist, null);
}
tblRecord user = arrList.get(position);
if (user != null) {
TextView c1 = (TextView) v.findViewById(R.id.txt1);
TextView c2 = (TextView) v.findViewById(R.id.txt2);
if (c1 != null) {
c1.setText(user.c1);
}
if(c2 != null) {
c2.setText(user.c2);
}
}
return v;
}
}
public class tblRecord {
public String c1;
public String c2;
public tblRecord(String c1, String c2) {
this.c1 = c1;
this.c2 = c2;
}
}
/** END Using a custom List View */
/** Listener for the spinner, we will handle changes made to the spinner here */
public class MyOnItemSelectedListener implements OnItemSelectedListener {
public void onItemSelected(AdapterView<?> parent,
View v, int position, long id) {
Toast.makeText(parent.getContext(), "The top " +
parent.getItemAtPosition(position).toString(), Toast.LENGTH_LONG).show();
}
public void onNothingSelected(AdapterView<?> parent) {
// Do nothing.
}
}
/** END Listener for the spinner, we will handle changes made to the spinner here */
#Override
public void onClick(View v) {
int id = v.getId();
// Intent myIntent;
switch (id) {
case R.id.ibQuit:
finish();
break;
}
}
}
Up until this point everything is working, if not 100% at least it works but now I need to try dynamically change the contents of the list view when the user changes the spinner.
The emulator uses -dns-server xxx.xxx.xxx.xxx in its run configuration
I am running 3.7in WVGA
Now after an 8 hour attempt to find a way to do this, this is as far as I have gotten but it just crashes:
package com.hunta.DDOFastestTimes;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.app.ListActivity;
import android.content.Context;
import android.net.ParseException;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
public class DDOFastestTimesActivity extends ListActivity implements OnClickListener {
private UserItemAdapter myAdapter;
private ArrayList<tblRecord> arrTxt = null;
private Runnable viewJSON;
/** JSON variables */
String jc1, jc2, result = null;
InputStream is = null;
StringBuilder sb = null;
/** END JSON variables */
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ImageButton closeApp = (ImageButton) findViewById(R.id.ibQuit);
closeApp.setOnClickListener(this);
/** http://www.dcpagesapps.com/developer-resources/android/21-android-tutorial-spinners?start=1 */
/** Populating the spinner from that string-array */
Spinner s = (Spinner) findViewById( R.id.spinTop );
ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource( this, R.array.strArrTop, android.R.layout.simple_spinner_item );
adapter.setDropDownViewResource( android.R.layout.simple_spinner_dropdown_item );
/** END Populating the spinner from that string-array */
/** Create a reference to our spinner */
s.setAdapter( adapter );
/** END Create a reference to our spinner */
/** END http://www.dcpagesapps.com/developer-resources/android/21-android-tutorial-spinners?start=1 */
s.setOnItemSelectedListener(new MyOnItemSelectedListener());
arrTxt = new ArrayList<tblRecord>();
this.myAdapter = new UserItemAdapter(this, R.layout.mylist, arrTxt);
setListAdapter(this.myAdapter);
viewJSON = new Runnable(){
#Override
public void run() {
arrTxt = MyJSONFetch(0);
}
};
Thread thread = new Thread(null, viewJSON, "MagentoBackground");
thread.start();
ListView myListView1 = (ListView) findViewById(R.id.list1);
myListView1.setAdapter(new UserItemAdapter(this, android.R.layout.simple_list_item_1, arrTxt));
}
/** End Called when the activity is first created. */
private Runnable returnRes = new Runnable() {
#Override
public void run() {
if(arrTxt != null && arrTxt.size() > 0){
myAdapter.notifyDataSetChanged();
for(int i=0;i<arrTxt.size();i++)
myAdapter.add(arrTxt.get(i));
}
myAdapter.notifyDataSetChanged();
}
};
/** Using a custom List View */
public class UserItemAdapter extends ArrayAdapter<tblRecord> {
private ArrayList<tblRecord> arrTxt;
public UserItemAdapter(Context context, int textViewResourceId, ArrayList<tblRecord> arrTxt) {
super(context, textViewResourceId, arrTxt);
this.arrTxt = arrTxt;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.mylist, null);
}
tblRecord user = arrTxt.get(position);
if (user != null) {
TextView c1 = (TextView) v.findViewById(R.id.txt1);
TextView c2 = (TextView) v.findViewById(R.id.txt2);
if (c1 != null) {
c1.setText(user.c1);
}
if(c2 != null) {
c2.setText(user.c2);
}
}
return v;
}
}
public class tblRecord {
public String c1;
public String c2;
public tblRecord(String c1, String c2) {
this.c1 = c1;
this.c2 = c2;
}
}
/** END Using a custom List View */
/** Reload JSON Database from onclick listener */
public ArrayList<tblRecord> MyJSONFetch(int position)
{
ArrayList<tblRecord> arrTxt = new ArrayList<tblRecord>();
String tmpUrl = null;
/** JSON code to initiate the php */
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
//http post
try{
HttpClient httpclient = new DefaultHttpClient();
switch (position)
{
case 0:
tmpUrl = "http://smutlow.comp-degree.uhi.ac.uk/UG409713/DDOFastestTimes/fastag.php";
break;
case 1:
tmpUrl = "http://smutlow.comp-degree.uhi.ac.uk/UG409713/DDOFastestTimes/fastas.php";
break;
}
HttpPost httppost = new HttpPost(tmpUrl);
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
}catch(Exception e){
Log.e("log_tag", "Error in http connection"+e.toString());
}
//convert response to string
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
sb = new StringBuilder();
sb.append(reader.readLine() + "\n");
String line="0";
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result=sb.toString();
}catch(Exception e){
Log.e("log_tag", "Error converting result "+e.toString());
}
//paring data
JSONArray jArray;
try{
jArray = new JSONArray(result);
JSONObject json_data=null;
// Adding the JSON data to the list view
int length = jArray.length();
List<String> listContents1 = new ArrayList<String>(length);
List<String> listContents2 = new ArrayList<String>(length);
// Changing the ListViews
for(int i=0;i<jArray.length();i++){
json_data = jArray.getJSONObject(i);
jc1 = json_data.getString("c1");
jc2 = json_data.getString("c2");
listContents1.add(json_data.getString("c1"));
listContents2.add(json_data.getString("c2"));
// Create an Array to pass to our custom view
tblRecord addRecord = new tblRecord(jc1, jc2);
arrTxt.add(addRecord);
}
// END Adding the JSON data to the list view
}
catch(JSONException e1){
Toast.makeText(getBaseContext(), "No Results Found" ,Toast.LENGTH_LONG).show();
} catch (ParseException e1) {
e1.printStackTrace();
}
/** END Reload JSON Database from onclick listener */
runOnUiThread(returnRes);
return arrTxt;
}
/** Listener for the spinner, we will handle changes made to the spinner here */
public class MyOnItemSelectedListener implements OnItemSelectedListener {
public void onItemSelected(AdapterView<?> parent,
View v, int position, long id) {
MyJSONFetch(position);
Toast.makeText(parent.getContext(), "The top " + parent.getItemAtPosition(position).toString(), Toast.LENGTH_LONG).show();
MyJSONFetch(position);
}
public void onNothingSelected(AdapterView<?> parent) {
// Do nothing.
}
}
/** END Listener for the spinner, we will handle changes made to the spinner here */
#Override
public void onClick(View v) {
int id = v.getId();
// Intent myIntent;
switch (id) {
case R.id.ibQuit:
finish();
break;
}
}
}
Basically Ive tried to seperate the JSON code from the onCreate and put it into its own public method so I can call it from the MyOnItemSelectedListener but I am out of ideas and have demonstrated my total lack of understanding of java.
Please if you respond try be a simplistic as possible with your answer.
Thank you in advance.
p.s. apologies if the layout isn't what it should be this is my first post
So I have found a solution to this perhaps someone might offer a better one but here is what I did:
Rather than try to fire the PHP I needed from the spinner I opted to use the spinner to load a new Intent with the relevant URL to the PHP I wanted to use added to a Bundle.
if (position == 0) {
Bundle myBundle = new Bundle();
Intent myIntent;
myBundle.putString("myPHP", "http://url-to-my-php-file/fastag.php");
myIntent = new Intent(getBaseContext(), DDOFastestGuilds.class);
myIntent.putExtras(myBundle);
startActivity(myIntent);
onLowMemory();
finish();
}
I then added two new .java files practically identical to the first one, adding two lines at the start:
Bundle myBundle = getIntent().getExtras();
String tmpPHP = myBundle.getString("myPHP");
I amended the line that calls the HttpPost to point to the variable I just created tmpPHP rather than the literal URL I had used in the original file:
HttpPost httppost = new HttpPost(tmpPHP);
And lastly changing the spinners selection to reflect that last selected by the user, if there were more than two options in the spinner I would have used the bundle to pass the last selected index but in my example I only had two options so I knew the selected index was either 0 or 1 depending on the Intent i wanted to open. (Making sure its directly after the setAdapter method):
s.setSelection(1);
Hoping for an alternative method going forward.
If anyone can suggest a way to only have to use one Activity to get the same result I would be grateful.