Skip to content

Commit 8b54d8c

Browse files
author
Sébastien Vitard
committed
Ready for step-2
1 parent dfcb00c commit 8b54d8c

21 files changed

Lines changed: 417 additions & 0 deletions

‎app/build.gradle‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,5 @@ android {
2020
dependencies {
2121
compile 'com.android.support:appcompat-v7:26.1.0'
2222
compile 'com.android.volley:volley:1.0.0'
23+
compile 'com.google.android.gms:play-services-maps:11.0.4'
2324
}

‎app/src/main/AndroidManifest.xml‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
android:supportsRtl="true"
1313
android:theme="@style/AppTheme">
1414

15+
<meta-data
16+
android:name="com.google.android.geo.API_KEY"
17+
android:value="@string/google_maps_key" />
18+
1519
<activity android:name=".main.MainActivity">
1620
<intent-filter>
1721
<action android:name="android.intent.action.MAIN" />
@@ -20,6 +24,8 @@
2024
</intent-filter>
2125
</activity>
2226

27+
<!-- TODO: declare the new activity and add it a new label too -->
28+
2329
</application>
2430

2531
</manifest>
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package io.kristal.events.detail;
2+
3+
import android.widget.Toast;
4+
5+
import io.kristal.events.R;
6+
import io.kristal.events.model.Event;
7+
8+
/**
9+
* Created by sebastien on 10/01/2018.
10+
*/
11+
12+
public final class CreateActivity extends DetailActivity {
13+
14+
public static final int RESULT_CREATED = -1;
15+
16+
@Override
17+
protected void onCheckOptionsItemSelected() {
18+
Event event = mDetail.getEvent();
19+
if (event != null) {
20+
// TODO: set result with created event & finish activity
21+
}
22+
else {
23+
Toast.makeText(this, R.string.check_error, Toast.LENGTH_LONG).show();
24+
}
25+
}
26+
}
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
package io.kristal.events.detail;
2+
3+
import android.location.Address;
4+
import android.location.Geocoder;
5+
import android.os.Bundle;
6+
import android.support.v7.app.AppCompatActivity;
7+
import android.util.Log;
8+
import android.view.Menu;
9+
import android.view.MenuInflater;
10+
import android.view.MenuItem;
11+
import android.widget.Toast;
12+
13+
import com.google.android.gms.maps.CameraUpdateFactory;
14+
import com.google.android.gms.maps.GoogleMap;
15+
import com.google.android.gms.maps.OnMapReadyCallback;
16+
import com.google.android.gms.maps.SupportMapFragment;
17+
import com.google.android.gms.maps.model.LatLng;
18+
import com.google.android.gms.maps.model.Marker;
19+
import com.google.android.gms.maps.model.MarkerOptions;
20+
21+
import java.io.IOException;
22+
import java.util.List;
23+
24+
import io.kristal.events.R;
25+
26+
/**
27+
* Created by sebastien on 10/01/2018.
28+
*/
29+
30+
public abstract class DetailActivity extends AppCompatActivity implements OnMapReadyCallback,
31+
GoogleMap.OnMapLongClickListener, PlaceTextListener {
32+
33+
protected static final String TAG = DetailActivity.class.getSimpleName();
34+
35+
public static String EXTRA_EVENT = "io.kristal.events.detail.DetailActivity.EXTRA_EVENT";
36+
37+
protected DetailFragment mDetail;
38+
private GoogleMap mMap;
39+
private Marker mMarker;
40+
private String mPendingPlace;
41+
42+
@Override
43+
protected void onCreate(Bundle savedInstanceState) {
44+
super.onCreate(savedInstanceState);
45+
46+
setContentView(R.layout.activity_detail);
47+
48+
mDetail = ((DetailFragment) getSupportFragmentManager().findFragmentById(R.id.detail));
49+
mDetail.setPlaceTextListener(this);
50+
51+
((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
52+
.getMapAsync(this);
53+
}
54+
55+
/***********************************************************************************************
56+
*
57+
* MENU
58+
*
59+
**********************************************************************************************/
60+
61+
@Override
62+
public boolean onCreateOptionsMenu(Menu menu) {
63+
MenuInflater inflater = getMenuInflater();
64+
inflater.inflate(R.menu.menu_detail, menu);
65+
66+
return super.onCreateOptionsMenu(menu);
67+
}
68+
69+
@Override
70+
public boolean onOptionsItemSelected(MenuItem item) {
71+
if (item.getItemId() == R.id.action_check) {
72+
onCheckOptionsItemSelected();
73+
return true;
74+
}
75+
else {
76+
return super.onOptionsItemSelected(item);
77+
}
78+
}
79+
80+
protected abstract void onCheckOptionsItemSelected();
81+
82+
/***********************************************************************************************
83+
*
84+
* MAP
85+
*
86+
**********************************************************************************************/
87+
88+
@Override
89+
public void onMapReady(GoogleMap googleMap) {
90+
mMap = googleMap;
91+
92+
mMap.setOnMapLongClickListener(this);
93+
94+
if (mPendingPlace != null) {
95+
setPlace(mPendingPlace);
96+
mPendingPlace = null;
97+
}
98+
else {
99+
LatLng latLng = new LatLng(48.732041, -3.459063);
100+
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 7));
101+
}
102+
}
103+
104+
@Override
105+
public void onMapLongClick(LatLng latLng) {
106+
String place = "Unknown";
107+
try {
108+
List<Address> addresses = new Geocoder(this).getFromLocation(latLng.latitude,
109+
latLng.longitude, 1);
110+
String locality = (addresses.isEmpty() ? null : addresses.get(0).getLocality());
111+
if (locality != null) {
112+
place = locality;
113+
}
114+
}
115+
catch (IOException exception) {
116+
Log.i(TAG, "onMapLongClick: network unavailable");
117+
exception.printStackTrace();
118+
}
119+
120+
if (mMarker == null) {
121+
mMarker = mMap.addMarker(new MarkerOptions().position(latLng).title(place));
122+
}
123+
else {
124+
mMarker.setPosition(latLng);
125+
mMarker.setTitle(place);
126+
}
127+
128+
onPlaceChanged(place);
129+
}
130+
131+
@Override
132+
public void onPlaceTextChanged(String place) {
133+
setPlace(place);
134+
}
135+
136+
private void setPlace(String place) {
137+
if (mMap != null) {
138+
try {
139+
List<Address> addresses = new Geocoder(this).getFromLocationName(place,
140+
1);
141+
if (! addresses.isEmpty()) {
142+
Address address = addresses.get(0);
143+
144+
LatLng latLng = new LatLng(address.getLatitude(), address.getLongitude());
145+
if (mMarker == null) {
146+
mMarker = mMap.addMarker(new MarkerOptions().position(latLng).title(place));
147+
}
148+
else {
149+
mMarker.setPosition(latLng);
150+
mMarker.setTitle(place);
151+
}
152+
if (mPendingPlace == null) {
153+
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
154+
}
155+
else {
156+
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 7));
157+
}
158+
}
159+
else {
160+
Toast.makeText(this, "No address found", Toast.LENGTH_LONG).show();
161+
}
162+
} catch (IOException exception) {
163+
Toast.makeText(this, "Network unavailable", Toast.LENGTH_SHORT).show();
164+
Log.i(TAG, "setPlace: network unavailable");
165+
exception.printStackTrace();
166+
}
167+
}
168+
else {
169+
mPendingPlace = place;
170+
}
171+
}
172+
173+
private void onPlaceChanged(String place) {
174+
mDetail.onPlaceChanged(place);
175+
}
176+
}
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
package io.kristal.events.detail;
2+
3+
import android.app.DatePickerDialog;
4+
import android.os.Bundle;
5+
import android.support.annotation.Nullable;
6+
import android.support.v4.app.Fragment;
7+
import android.util.Log;
8+
import android.view.KeyEvent;
9+
import android.view.LayoutInflater;
10+
import android.view.View;
11+
import android.view.ViewGroup;
12+
import android.widget.DatePicker;
13+
import android.widget.EditText;
14+
15+
import java.text.DateFormat;
16+
import java.text.ParseException;
17+
import java.util.Calendar;
18+
import java.util.Date;
19+
20+
import io.kristal.events.R;
21+
import io.kristal.events.model.Event;
22+
23+
/**
24+
* Created by sebastien on 10/01/2018.
25+
*/
26+
27+
public final class DetailFragment extends Fragment implements DatePickerDialog.OnDateSetListener {
28+
29+
private static final String TAG = DetailFragment.class.getSimpleName();
30+
31+
private static DateFormat sDateFormat = DateFormat.getDateInstance(DateFormat.SHORT);
32+
33+
private Event mEvent;
34+
private PlaceTextListener mListener;
35+
36+
private EditText mEditTitle;
37+
private EditText mEditDate;
38+
private EditText mEditPlace;
39+
40+
@Override
41+
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
42+
@Nullable Bundle savedInstanceState) {
43+
View view = inflater.inflate(R.layout.fragment_detail, container, false);
44+
45+
mEditTitle = view.findViewById(R.id.form_title);
46+
mEditDate = view.findViewById(R.id.form_date);
47+
mEditPlace = view.findViewById(R.id.form_place);
48+
49+
return view;
50+
}
51+
52+
@Nullable
53+
Event getEvent() {
54+
Date date;
55+
try {
56+
date = sDateFormat.parse(mEditDate.getText().toString());
57+
}
58+
catch(ParseException exception) {
59+
Log.e(TAG, "getEvent: date parsing failed");
60+
exception.printStackTrace();
61+
return null;
62+
}
63+
64+
String title = mEditTitle.getText().toString();
65+
String place = mEditPlace.getText().toString();
66+
67+
if (mEvent != null) {
68+
mEvent.setDate(date);
69+
mEvent.setTitle(title);
70+
mEvent.setPlace(place);
71+
}
72+
else {
73+
mEvent = new Event(getContext(), title, date, place);
74+
}
75+
76+
return mEvent;
77+
}
78+
79+
/***********************************************************************************************
80+
*
81+
* DATE PICKER
82+
*
83+
**********************************************************************************************/
84+
85+
private void showDatePicker() {
86+
Calendar calendar = Calendar.getInstance();
87+
if (mEvent != null) {
88+
calendar.setTime(mEvent.getDate());
89+
}
90+
91+
new DatePickerDialog(getContext(), this,
92+
calendar.get(Calendar.YEAR),
93+
calendar.get(Calendar.MONTH),
94+
calendar.get(Calendar.DAY_OF_MONTH)).show();
95+
}
96+
97+
@Override
98+
public void onDateSet(DatePicker view, int year, int month, int dayOfMonth) {
99+
Calendar calendar = Calendar.getInstance();
100+
calendar.clear();
101+
calendar.set(year, month, dayOfMonth);
102+
mEditDate.setText(sDateFormat.format(calendar.getTime()));
103+
}
104+
105+
/***********************************************************************************************
106+
*
107+
* MAP
108+
*
109+
**********************************************************************************************/
110+
111+
private void bindPlaceTextListener() {
112+
mEditPlace.setOnKeyListener(new View.OnKeyListener() {
113+
@Override
114+
public boolean onKey(View v, int keyCode, KeyEvent event) {
115+
if (event.getAction() == KeyEvent.ACTION_DOWN
116+
&& keyCode == KeyEvent.KEYCODE_ENTER) {
117+
if (mListener != null) {
118+
mListener.onPlaceTextChanged(mEditPlace.getText().toString());
119+
}
120+
return true;
121+
}
122+
123+
return false;
124+
}
125+
});
126+
}
127+
128+
void setPlaceTextListener(PlaceTextListener listener) {
129+
mListener = listener;
130+
bindPlaceTextListener();
131+
}
132+
133+
@Override
134+
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
135+
super.onActivityCreated(savedInstanceState);
136+
137+
String place = mEditPlace.getText().toString();
138+
if (place.length() > 0
139+
&& mListener != null) {
140+
mListener.onPlaceTextChanged(place);
141+
}
142+
}
143+
144+
void onPlaceChanged(String place) {
145+
mEditPlace.setText(place);
146+
}
147+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package io.kristal.events.detail;
2+
3+
/**
4+
* Created by sebastien on 10/01/2018.
5+
*/
6+
7+
interface PlaceTextListener {
8+
9+
void onPlaceTextChanged(String place);
10+
}
248 Bytes
Loading
427 Bytes
Loading
164 Bytes
Loading
252 Bytes
Loading

0 commit comments

Comments
 (0)