This commit is contained in:
marcin.jedynski 2018-11-27 06:21:19 +01:00
commit 50ef5b1e8b
24 changed files with 301 additions and 129 deletions

View File

@ -154,11 +154,8 @@ public class LoginActivity extends AppCompatActivity {
private void loginProcess(String email, String password) {
ValidateUser user = new ValidateUser(email, password);
LdapUser fuser = new LdapUser(email,password,"wmi","tutor","henryk","zdzblo",email);
// disposable.add(ldapService.validate(user)
disposable.add(ldapService.fakeValidate(fuser)
disposable.add(ldapService.validate(user)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::handleResponse, this::handleError));
@ -185,7 +182,9 @@ public class LoginActivity extends AppCompatActivity {
Claim userId = jwt.getClaim("nameid");
Claim role = jwt.getClaim("http://schemas.microsoft.com/ws/2008/06/identity/claims/role");
if(!Objects.requireNonNull(role.asString()).equals("Student")){
if(Objects.requireNonNull(role.asString()).equals("Student")){
PrefUtils.storeIsTutor(getApplicationContext(), false);
}else{
PrefUtils.storeIsTutor(getApplicationContext(), true);
}
@ -220,6 +219,5 @@ public class LoginActivity extends AppCompatActivity {
PrefUtils.storeUserLastName(getApplicationContext(), user.getLastName());
PrefUtils.storeUserName(getApplicationContext(), user.getUserName());
}
}

View File

@ -4,6 +4,7 @@ import android.Manifest;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.graphics.Color;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
@ -44,8 +45,10 @@ import com.uam.wmi.findmytutor.service.CoordinateService;
import com.uam.wmi.findmytutor.service.UserService;
import com.uam.wmi.findmytutor.utils.FeedbackUtils;
import com.uam.wmi.findmytutor.utils.ManualLocationUtils;
import com.uam.wmi.findmytutor.utils.MapMarker;
import com.uam.wmi.findmytutor.utils.PrefUtils;
import com.uam.wmi.findmytutor.utils.RestApiHelper;
import com.uam.wmi.findmytutor.utils.SharingLevel;
import com.uam.wmi.findmytutor.utils.mapUtils;
import java.util.ArrayList;
@ -61,11 +64,9 @@ import io.reactivex.schedulers.Schedulers;
import okhttp3.ResponseBody;
import timber.log.Timber;
public class MapActivity extends BaseActivity
implements PermissionsListener, OnMapReadyCallback {
private String tag = getClass().getName();
private PermissionsManager permissionsManager;
private LocationComponent locationComponent;
@ -85,21 +86,22 @@ public class MapActivity extends BaseActivity
private Marker tmpLocalMarker;
private Coordinate droppedMarkercoordinate;
private HashMap<String, Coordinate> coordsMap = new HashMap<>();
private HashMap<String, Marker> markerHash = new HashMap<>();
private HashMap<String, MapMarker> markerHash = new HashMap<>();
private HashMap<Long, String> markerUserHash = new HashMap<>();
private Set<String> previousCoordsIds = new HashSet<>();
private ManualLocationUtils manualLocationUtils;
// Camera Animation params
private int zoomParam = 17;
private int bearingParam = 180;
private int tiltParam = 30;
private String myID;
private String myId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myID = PrefUtils.getUserId(getApplicationContext());
// fetching coords service
myId = PrefUtils.getUserId(getApplicationContext());
coordinateService = ApiClient.getClient(getApplicationContext())
.create(CoordinateService.class);
@ -115,9 +117,6 @@ public class MapActivity extends BaseActivity
manualLocationUtils = new ManualLocationUtils(MapActivity.this);
};
Bundle extras = getIntent().getExtras();
selectLocationButton = findViewById(R.id.select_location_button);
removeLocationButton = findViewById(R.id.remove_location_button);
Mapbox.getInstance(this, getString(R.string.access_token));
@ -136,8 +135,9 @@ public class MapActivity extends BaseActivity
enableLocationPlugin();
mapboxMap.setOnMarkerClickListener(marker -> {
String id = marker.getTitle();
if (id.equals(myID)) {
String id = markerUserHash.get(marker.getId());
if (id.equals(myId)) {
selectLocationButton.setVisibility(View.GONE);
removeLocationButton.setVisibility(View.VISIBLE);
@ -145,9 +145,6 @@ public class MapActivity extends BaseActivity
Log.e(tag + "Manual", "manual coords sending stopped");
stopBackgroundLocalizationTask();
// TODO to remove after BGserv
// manualLocHandler.removeCallbacks(manualLocStatusChecker);
removeLocationButton.setVisibility(View.GONE);
Toast.makeText(MapActivity.this, "Your marker will disappear in next couple minutes", Toast.LENGTH_SHORT).show();
@ -159,12 +156,11 @@ public class MapActivity extends BaseActivity
return true;
});
setToggleMapBoundsArea();
if (PrefUtils.getIsTutor(this)){
if (PrefUtils.getIsTutor(this)) {
setOnMapLongClickListener();
}
// addStaticLayer();
}
private void setToggleMapBoundsArea() {
@ -184,15 +180,28 @@ public class MapActivity extends BaseActivity
});
}
private void updateUserHashMap(String userId, Long markerId) {
disposable.add(userService.getUserById(userId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(t -> saveUserToHashMap(t, markerId), this::handleError));
}
private void saveUserToHashMap(User user, Long markerId) {
markerUserHash.put(markerId, user.getId());
markerHash.get(user.getId()).getMarker().setTitle(user.getFirstName() + " " + user.getLastName());
}
private void createMarkerModal(String userId) {
disposable.add(userService.getUserById(userId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::createMarkerModal, this::handleError));
.subscribe(this::createMarkerModalView, this::handleError));
}
private void createMarkerModal(User user) {
private void createMarkerModalView(User user) {
String cordStatus = coordsMap.get(user.getId()).getLabel();
String sharingLevel = coordsMap.get(user.getId()).getDisplayMode();
LayoutInflater layoutInflaterAndroid = LayoutInflater.from(getApplicationContext());
@SuppressLint("InflateParams") View view = layoutInflaterAndroid.inflate(R.layout.marker_modal, null);
@ -206,12 +215,13 @@ public class MapActivity extends BaseActivity
TextView userName = view.findViewById(R.id.userName);
TextView status = view.findViewById(R.id.label);
TextView sharingLevelView = view.findViewById(R.id.sharing_level);
userName.setText(String.format("%s %s", user.getFirstName(), user.getLastName()));
status.setText(String.format("%s ", cordStatus));
status.setText(String.format("%s: %s", getResources().getString(R.string.status_switch_title), cordStatus));
sharingLevelView.setText(String.format("%s: %s", getResources().getString(R.string.settings_location_level), sharingLevel));
final AlertDialog alertDialog = alertDialogBuilderUserInput.create();
alertDialog.show();
}
@ -230,7 +240,6 @@ public class MapActivity extends BaseActivity
message = "Network Error!";
}
Toast.makeText(MapActivity.this, message, Toast.LENGTH_SHORT).show();
}
@ -240,7 +249,7 @@ public class MapActivity extends BaseActivity
mapboxMap.addOnMapLongClickListener((LatLng latLng) -> {
selectLocationButton.setVisibility(View.VISIBLE);
removeLocationButton.setVisibility(View.GONE);
Icon icon = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.green_marker);
Icon icon = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.my_marker);
if (tmpLocalMarker == null) {
@ -274,45 +283,6 @@ public class MapActivity extends BaseActivity
manualLocationUtils.showLocationDialog("Name the location",latLng);
handleBackgroundTaskLifeCycle();
// // TODO remove after BG sending
// manualLocStatusChecker = () -> {
// try {
// Log.e(tag + "Manual", "sending manual coords");
// // TODO ^^^ wrapper to removve
// disposable.add(
// coordinateService
// .postCoordinate(droppedMarkercoordinate)
// .subscribeOn(Schedulers.io())
// .observeOn(AndroidSchedulers.mainThread())
// .subscribeWith(new DisposableSingleObserver<Coordinate>() {
// @SuppressLint("LongLogTag")
// @Override
// public void onSuccess(Coordinate coord) {
// Log.e(tag + "POST", String.valueOf(coord));
// }
//
// @SuppressLint("LongLogTag")
// @Override
// public void onError(Throwable e) {
//
// Log.e(tag + "onError", e.getMessage());
//
// if (e instanceof HttpException) {
// ResponseBody responseBody = ((HttpException) e).response().errorBody();
// Log.e(tag + "onError", RestApiHelper.getErrorMessage(responseBody));
//
// }
// }
// }));
// // TODO \/\/\/\/\/ wrapper to removve
// } finally {
// manualLocHandler.postDelayed(manualLocStatusChecker, mInterval);
// }
// };
// manualLocStatusChecker.run();
} catch (IllegalArgumentException e) {
Timber.e(String.valueOf(e));
}
@ -352,7 +322,7 @@ public class MapActivity extends BaseActivity
if (tmpLocalMarker != null && coordsList.isEmpty()) {
Timber.e("200 empty []");
mapboxMap.clear();
return;
}
ArrayList<String> tmp = new ArrayList<>();
@ -365,36 +335,39 @@ public class MapActivity extends BaseActivity
previousCoordsIds.addAll(currentCoordsIds);
} else {
// here we clear + it returns bool if sth was removed
if (previousCoordsIds.removeAll(currentCoordsIds)) {
for (String toRemoveId : previousCoordsIds) {
Log.e(tag + "delete: ", "removing: " + toRemoveId + ": " + markerHash.get(toRemoveId));
mapboxMap.removeMarker(markerHash.get(toRemoveId));
markerHash.remove(toRemoveId);
coordsMap.remove(toRemoveId);
}
} else {
// TODO double check when some markers api will change
Log.e(tag + "delete: ", "nothing to remove");
previousCoordsIds.removeAll(currentCoordsIds);
for (String toRemoveId : previousCoordsIds) {
Log.e(tag + "delete: ", "removing: " + toRemoveId + ": " + markerHash.get(toRemoveId));
mapboxMap.removeMarker(markerHash.get(toRemoveId).getMarker());
markerHash.remove(toRemoveId);
coordsMap.remove(toRemoveId);
}
}
for (Coordinate element : coordsList) {
String id = element.getUserId();
String newLabel = element.getLabel();
String newSharingLevel = element.getDisplayMode();
Coordinate coordinate = coordsMap.get(id);
Log.e(tag, "hashMapSize: " + coordsMap.size());
Log.e(tag, "markerMapSize: " + coordsMap.size());
if (coordinate != null) {
Log.e(tag, "Coordin: " + coordinate.getLatitude() + " | " + coordinate.getLongitude());
boolean statement = coordinate.getLatitude().equals(element.getLatitude()) || coordinate.getLongitude().equals(element.getLongitude());
Log.e(tag, "diff || diff: " + !statement);
if (!statement) {
Log.e(tag, "replace and animate");
Marker marker = markerHash.get(id);
boolean isTheSameLocalization = coordinate.getLatitude().equals(element.getLatitude()) || coordinate.getLongitude().equals(element.getLongitude());
if (!isTheSameLocalization) {
//Replace prev marker and animate
Marker marker = markerHash.get(id).getMarker();
Boolean showModalAfterAnimation = false;
if(marker.isInfoWindowShown()){
marker.hideInfoWindow();
showModalAfterAnimation = true;
}
LatLng toDestination = new LatLng(element.getLatitude(), element.getLongitude());
// TODO fix flickiering markers
@ -406,29 +379,54 @@ public class MapActivity extends BaseActivity
markerAnimator.setInterpolator(new LinearInterpolator());
markerAnimator.start();
// chba niepotrzbene
mapboxMap.getMarkerViewManager().update();
coordsMap.put(id, element);
marker.setPosition(toDestination);
}
} else {
Log.e(tag, "Marker Added: " + id);
if(showModalAfterAnimation){
mapboxMap.selectMarker(marker);
}
mapboxMap.getMarkerViewManager().update();
}
} else {
//Add new marker
coordsMap.put(id, element);
String sharingLevel = coordsMap.get(id).getDisplayMode();
Icon defaultIcon = getMapIcon(sharingLevel, id);
MarkerOptions markerOptions = new MarkerOptions()
.title(id)
.setIcon(defaultIcon)
.position(new LatLng(element.getLatitude(), element.getLongitude()));
// Check if this is me
if (id.equals(myID)) {
Icon icon = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.blue_marker);
markerOptions.setIcon(icon);
}
Marker marker = mapboxMap.addMarker(markerOptions);
Marker markerMapbox = mapboxMap.addMarker(markerOptions);
MapMarker marker = new MapMarker(markerMapbox, markerOptions, defaultIcon, sharingLevel);
markerHash.put(id, marker);
updateUserHashMap(id, marker.getMarker().getId());
}
//Change marker if sharing mode has been changed
Boolean newLocalizationMode = markerHash.get(id).getMarkerType().equals(newSharingLevel);
if (!newLocalizationMode) {
Icon defaultIcon = getMapIcon(newSharingLevel, id);
MapMarker marker = markerHash.get(id);
coordsMap.get(id).setDisplayMode(newSharingLevel);
marker.setDefaultIcon(defaultIcon);
marker.restoreDefaultIcon();
markerHash.get(id).setMarkerType(newSharingLevel);
mapboxMap.getMarkerViewManager().update();
}
coordsMap.get(id).setLabel(newLabel);
@ -437,24 +435,42 @@ public class MapActivity extends BaseActivity
// For next fetch
previousCoordsIds.clear();
previousCoordsIds.addAll(currentCoordsIds);
for (Coordinate coordinate : coordsMap.values()) {
// 300000 = 5mins
if ((System.currentTimeMillis() - coordinate.getTimeStamp()) > (long) 300000) {
String id = coordinate.getUserId();
Marker markerToRemove = markerHash.get(id).getMarker();
markerHash.remove(id);
coordsMap.remove(id);
mapboxMap.removeMarker(markerToRemove);
}
}
}
@SuppressLint("LongLogTag")
@Override
public void onError(Throwable e) {
Log.e("MapActivity onError", e.getMessage());
if (e instanceof HttpException) {
ResponseBody responseBody = ((HttpException) e).response().errorBody();
Log.e("MapActivity onError", RestApiHelper.getErrorMessage(responseBody));
}
showError(e);
}
})
);
}
private Icon getMapIcon(String sharingLevel, String id) {
Icon defaultIcon = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.exact_localization_marker);
if (sharingLevel.equals(SharingLevel.APPROXIMATED.toString())) {
defaultIcon = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.approximate_localization_marker);
} else if (sharingLevel.equals(SharingLevel.MANUAL.toString()) ||
sharingLevel.equals(SharingLevel.PREDEFINED.toString()) ) {
defaultIcon = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.manual_localization_marker);
} else if (id.equals(myId)) {
defaultIcon = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.my_marker);
}
return defaultIcon;
}
@SuppressWarnings({"MissingPermission"})
private void enableLocationPlugin() {
@ -577,7 +593,6 @@ public class MapActivity extends BaseActivity
@Override
public void onRequestPermissionsResult(int requestCode, @android.support.annotation.NonNull String[] permissions, @android.support.annotation.NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
// permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
@Override
@ -624,23 +639,32 @@ public class MapActivity extends BaseActivity
private void filterMarkers(List<User> users) {
restoreMapMarkers();
Icon icon1 = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.custom_marker);
List<Marker> markersToSet = Stream.of(mapboxMap.getMarkers())
.filter(m -> Stream.of(users).anyMatch(u -> u.getId().equals(m.getTitle())))
Icon markedMarker = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.search_marker);
List<MapMarker> markersToSet = Stream.of(mapboxMap.getMarkers())
.filter(m -> Stream.of(users).anyMatch(u -> u.getId().equals(markerUserHash.get(m.getId()))))
.map(m -> markerUserHash.get(m.getId()))
.map(m -> markerHash.get(m))
.toList();
for (Marker marker : markersToSet) {
marker.setIcon(icon1);
for (MapMarker marker : markersToSet) {
marker.getMarker().setIcon(markedMarker);
if(markersToSet.size() == 1)
mapboxMap.selectMarker(marker.getMarker());
}
mapboxMap.getMarkerViewManager().update();
}
public void restoreMapMarkers() {
Icon icon = IconFactory.getInstance(MapActivity.this).fromResource(R.drawable.red_marker);
for (Marker marker : mapboxMap.getMarkers()) {
marker.setIcon(icon);
}
}
MapMarker markerMap = markerHash.get(markerUserHash.get(marker.getId()));
markerMap.restoreDefaultIcon();
mapboxMap.deselectMarker(marker);
}
mapboxMap.getMarkerViewManager().update();
}
}

View File

@ -162,8 +162,10 @@ public class SharingFragment extends PreferenceFragment {
/** Sharing level list **/
// locationMode.setSummary(PrefUtils.getLocationLevel(getApplicationContext()));
locationMode.setOnPreferenceChangeListener((preference, newValue) -> {
PrefUtils.storeLocationMode(getApplicationContext(), locationLevelMapping.get(Integer.parseInt((String) newValue)));
if (PrefUtils.getLocationLevel(getApplicationContext()).equals("manual") ) {
preferenceCategory.addPreference(manualLocationList);
getLocations(disposable);
preferenceCategory.addPreference(manualLocationButton);
@ -194,15 +196,12 @@ public class SharingFragment extends PreferenceFragment {
return true;
});
/** Button 'choose from map' button listener **/
manualLocationButton.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
@Override
public boolean onPreferenceChange(Preference preference, Object o) {
//ToDO wywołanie wybierania lokalizacji z mapy
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.hide(SharingFragment.this);
fragmentTransaction.commit();
return true;
}
manualLocationButton.setOnPreferenceChangeListener((preference, o) -> {
//ToDO wywołanie wybierania lokalizacji z mapy
FragmentTransaction fragmentTransaction = getFragmentManager().beginTransaction();
fragmentTransaction.hide(SharingFragment.this);
fragmentTransaction.commit();
return true;
});
/** Status list change listener **/

View File

@ -0,0 +1,31 @@
package com.uam.wmi.findmytutor.activity;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import com.uam.wmi.findmytutor.R;
public class TutorTab extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_tutor_tab);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
}

View File

@ -0,0 +1,65 @@
package com.uam.wmi.findmytutor.utils;
import android.support.annotation.NonNull;
import android.view.View;
import com.mapbox.mapboxsdk.annotations.Icon;
import com.mapbox.mapboxsdk.annotations.InfoWindow;
import com.mapbox.mapboxsdk.annotations.Marker;
import com.mapbox.mapboxsdk.annotations.MarkerOptions;
import com.mapbox.mapboxsdk.maps.MapView;
import com.mapbox.mapboxsdk.maps.MapboxMap;
public class MapMarker{
private MarkerOptions markerOptions;
private Marker marker;
private String markerType;
private Icon defaultIcon;
private Icon markerIcon;
public MapMarker(Marker marker, MarkerOptions markerOptions, Icon icon, String markerType) {
this.setMarker(marker);
this.setMarkerOptions(markerOptions);
this.defaultIcon = icon;
this.markerType = markerType;
}
public void restoreDefaultIcon() {
this.marker.setIcon(this.defaultIcon);
}
public void setDefaultIcon(Icon icon) {
this.defaultIcon = icon;
}
private void changeMarkerType(String markerType) {
this.markerType = markerType;
}
public MarkerOptions getMarkerOptions() {
return markerOptions;
}
private void setMarkerOptions(MarkerOptions marker) {
this.markerOptions = marker;
}
public Marker getMarker() {
return marker;
}
public void setMarker(Marker marker) {
this.marker = marker;
}
public String getMarkerType() {
return markerType;
}
public void setMarkerType(String markerType) {
this.markerType = markerType;
}
}

View File

@ -4,6 +4,7 @@ public enum SharingLevel {
PRESENCE("presence"),
APPROXIMATED("approximated"),
EXACT("exact"),
PREDEFINED("predefined"),
MANUAL("manual");
private final String text;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 923 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 923 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 444 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

View File

@ -16,7 +16,7 @@
mapbox:mapbox_cameraTargetLat="52.466799"
mapbox:mapbox_cameraTargetLng="16.927002"
mapbox:mapbox_cameraZoom="17"
mapbox:mapbox_styleUrl="mapbox://styles/domagalsky/cjiyzrqjp05l72rmj6ntvv2n8">
mapbox:mapbox_styleUrl="mapbox://styles/domagalsky/cjo8yjhfj0ih02rld5rft5nv7">
</com.mapbox.mapboxsdk.maps.MapView>

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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="match_parent"
android:layout_height="match_parent"
tools:context=".activity.TutorTab">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_tutor_tab" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="@dimen/fab_margin"
app:srcCompat="@android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".activity.TutorTab"
tools:showIn="@layout/activity_tutor_tab">
</android.support.constraint.ConstraintLayout>

View File

@ -27,4 +27,14 @@
android:textColor="@color/note_list_text"
/>
<TextView
android:id="@+id/sharing_level"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:lineSpacingExtra="8sp"
android:paddingTop="5dp"
android:textColor="@color/note_list_text"
/>
</LinearLayout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB