6 Commits
v0.2 ... v0.3

11 changed files with 248 additions and 110 deletions

17
.idea/deploymentTargetDropDown.xml generated Normal file
View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetDropDown">
<targetSelectedWithDropDown>
<Target>
<type value="QUICK_BOOT_TARGET" />
<deviceKey>
<Key>
<type value="VIRTUAL_DEVICE_PATH" />
<value value="$USER_HOME$/.android/avd/Pixel_XL_API_30.avd" />
</Key>
</deviceKey>
</Target>
</targetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2021-09-14T16:48:49.750165Z" />
</component>
</project>

1
.idea/misc.xml generated
View File

@ -4,6 +4,7 @@
<option name="filePathToZoomLevelMap"> <option name="filePathToZoomLevelMap">
<map> <map>
<entry key="../../../../layout/custom_preview.xml" value="0.5661458333333333" /> <entry key="../../../../layout/custom_preview.xml" value="0.5661458333333333" />
<entry key="app/src/main/res/drawable/ic_map_pin.xml" value="0.6425925925925926" />
<entry key="app/src/main/res/layout/activity_geofavorite_detail.xml" value="0.4" /> <entry key="app/src/main/res/layout/activity_geofavorite_detail.xml" value="0.4" />
<entry key="app/src/main/res/layout/activity_list_view.xml" value="0.5307291666666667" /> <entry key="app/src/main/res/layout/activity_list_view.xml" value="0.5307291666666667" />
<entry key="app/src/main/res/layout/activity_main.xml" value="0.5307291666666667" /> <entry key="app/src/main/res/layout/activity_main.xml" value="0.5307291666666667" />

View File

@ -9,3 +9,4 @@ A new geobookmark can be created on current location.
This work is heavily based on [matiasdelellis's Nextcloud SSO example](https://github.com/matiasdelellis/app-tutorial-android) to implement [Nextcloud single sign on](https://github.com/nextcloud/Android-SingleSignOn). This work is heavily based on [matiasdelellis's Nextcloud SSO example](https://github.com/matiasdelellis/app-tutorial-android) to implement [Nextcloud single sign on](https://github.com/nextcloud/Android-SingleSignOn).
![Screenshot 1](screenshots/1.png) ![Screenshot 1](screenshots/2.png)

View File

@ -55,15 +55,15 @@ dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"]) implementation fileTree(dir: "libs", include: ["*.jar"])
implementation 'com.android.support:design:30.0.1' implementation 'com.android.support:design:30.0.1'
implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'androidx.recyclerview:recyclerview:1.1.0' implementation 'androidx.recyclerview:recyclerview:1.2.1'
implementation "androidx.cardview:cardview:1.0.0" implementation "androidx.cardview:cardview:1.0.0"
implementation 'androidx.constraintlayout:constraintlayout:2.0.1' implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
implementation "androidx.preference:preference:1.1.1" implementation "androidx.preference:preference:1.1.1"
testImplementation 'junit:junit:4.13' testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
// Retrofif2 // Retrofif2
implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:retrofit:2.9.0'
@ -71,4 +71,8 @@ dependencies {
// Nextcloud SSO // Nextcloud SSO
implementation "com.github.nextcloud:Android-SingleSignOn:0.5.6" implementation "com.github.nextcloud:Android-SingleSignOn:0.5.6"
// OSMDroid
compile 'org.osmdroid:osmdroid-android:6.1.10'
} }

View File

@ -34,7 +34,15 @@ import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.core.app.ActivityCompat; import androidx.core.app.ActivityCompat;
import androidx.preference.PreferenceManager;
import org.osmdroid.api.IMapController;
import org.osmdroid.config.Configuration;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.CustomZoomButtonsController;
import org.osmdroid.views.overlay.Marker;
import java.util.Date; import java.util.Date;
@ -61,9 +69,28 @@ public class GeofavoriteDetailActivity extends AppCompatActivity implements Loca
protected void onCreate(@Nullable Bundle savedInstanceState) { protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
// OSMDroid config
Configuration.getInstance().load(getApplicationContext(),
PreferenceManager.getDefaultSharedPreferences(getApplicationContext()));
mViewHolder = new ViewHolder(getLayoutInflater()); mViewHolder = new ViewHolder(getLayoutInflater());
mViewHolder.setOnSubmitListener(this::saveGeofavorite);
setContentView(mViewHolder.getRootView()); setContentView(mViewHolder.getRootView());
mViewHolder.setOnSubmitListener(new OnSubmitListener() {
@Override
public void onBackPressed() {
finish();
}
@Override
public void onSubmit() {
saveGeofavorite();
}
@Override
public void onMapClicked() {
Toast.makeText(GeofavoriteDetailActivity.this, "TODO: Open map activity with pin", Toast.LENGTH_SHORT).show();
}
});
if (getIntent().hasExtra(ARG_GEOFAVORITE)) { if (getIntent().hasExtra(ARG_GEOFAVORITE)) {
// Opening geofavorite from list // Opening geofavorite from list
@ -83,6 +110,24 @@ public class GeofavoriteDetailActivity extends AppCompatActivity implements Loca
} }
@Override
protected void onResume() {
super.onResume();
// OSMDroid config
Configuration.getInstance().load(getApplicationContext(),
PreferenceManager.getDefaultSharedPreferences(getApplicationContext()));
mViewHolder.onResume();
}
@Override
protected void onPause() {
// OSMDroid config
Configuration.getInstance().save(getApplicationContext(),
PreferenceManager.getDefaultSharedPreferences(getApplicationContext()));
mViewHolder.onPause();
super.onPause();
}
/** /**
* Called when the submit button is clicked * Called when the submit button is clicked
* @param v The button * @param v The button
@ -166,7 +211,7 @@ public class GeofavoriteDetailActivity extends AppCompatActivity implements Loca
mGeofavorite.setLat(location.getLatitude()); mGeofavorite.setLat(location.getLatitude());
mGeofavorite.setLng(location.getLongitude()); mGeofavorite.setLng(location.getLongitude());
// Update view // Update view
mViewHolder.updateViewCoords(mGeofavorite.getCoordinatesString()); mViewHolder.updateViewCoords(mGeofavorite);
mViewHolder.setAccuracy(location.getAccuracy()); mViewHolder.setAccuracy(location.getAccuracy());
} }
@ -211,10 +256,23 @@ public class GeofavoriteDetailActivity extends AppCompatActivity implements Loca
private class ViewHolder implements View.OnClickListener { private class ViewHolder implements View.OnClickListener {
private final ActivityGeofavoriteDetailBinding binding; private final ActivityGeofavoriteDetailBinding binding;
private OnSubmitListener listener; private OnSubmitListener listener;
private Marker mapMarker;
public ViewHolder(LayoutInflater inflater) { public ViewHolder(LayoutInflater inflater) {
this.binding = ActivityGeofavoriteDetailBinding.inflate(inflater); this.binding = ActivityGeofavoriteDetailBinding.inflate(inflater);
this.binding.submitBt.setOnClickListener(this); this.binding.submitBt.setOnClickListener(this);
this.binding.mapBt.setOnClickListener(this);
this.binding.backBt.setOnClickListener(this);
// Set map properties
this.binding.map.getZoomController().setVisibility(CustomZoomButtonsController.Visibility.NEVER);
this.binding.map.setMultiTouchControls(true);
// Create marker
mapMarker = new Marker(binding.map);
mapMarker.setIcon(AppCompatResources.getDrawable(GeofavoriteDetailActivity.this, R.drawable.ic_map_pin));
mapMarker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM);
binding.map.getOverlays().add(mapMarker);
} }
public View getRootView() { public View getRootView() {
@ -227,11 +285,20 @@ public class GeofavoriteDetailActivity extends AppCompatActivity implements Loca
binding.createdTv.setText(new Date(item.getDateCreated() * 1000).toString()); binding.createdTv.setText(new Date(item.getDateCreated() * 1000).toString());
binding.modifiedTv.setText(new Date(item.getDateModified() * 1000).toString()); binding.modifiedTv.setText(new Date(item.getDateModified() * 1000).toString());
binding.categoryTv.setText(item.getCategory()); // TODO: Category spinner from existing categories binding.categoryTv.setText(item.getCategory()); // TODO: Category spinner from existing categories
binding.coordsTv.setText(item.getCoordinatesString()); updateViewCoords(item);
} }
public void updateViewCoords(String coords) { public void updateViewCoords(Geofavorite item) {
binding.coordsTv.setText(coords); binding.coordsTv.setText(item.getCoordinatesString());
// Center map
GeoPoint position = new GeoPoint(item.getLat(), item.getLng());
IMapController mapController = binding.map.getController();
mapController.setZoom(19.0f);
mapController.setCenter(position);
// Set pin
mapMarker.setPosition(position);
} }
public void updateModel(Geofavorite item) { public void updateModel(Geofavorite item) {
@ -258,15 +325,31 @@ public class GeofavoriteDetailActivity extends AppCompatActivity implements Loca
this.listener = listener; this.listener = listener;
} }
public void onResume() {
binding.map.onResume();
}
public void onPause() {
binding.map.onPause();
}
@Override @Override
public void onClick(View v) { public void onClick(View v) {
if (v.getId() == R.id.submit_bt && this.listener != null) { if (v.getId() == R.id.submit_bt && this.listener != null) {
this.listener.onSubmit(); this.listener.onSubmit();
} }
if (v.getId() == R.id.map_bt && this.listener != null) {
this.listener.onMapClicked();
}
if (v.getId() == R.id.back_bt && this.listener != null) {
this.listener.onBackPressed();
}
} }
} }
protected interface OnSubmitListener { protected interface OnSubmitListener {
void onSubmit(); void onSubmit();
void onMapClicked();
void onBackPressed();
} }
} }

View File

@ -0,0 +1,5 @@
<vector android:height="48dp" android:tint="#0082C9"
android:viewportHeight="24" android:viewportWidth="24"
android:width="48dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="@android:color/white" android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13c0,-3.87 -3.13,-7 -7,-7zM12,11.5c-1.38,0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5 2.5,1.12 2.5,2.5 -1.12,2.5 -2.5,2.5z"/>
</vector>

View File

@ -2,127 +2,150 @@
<layout xmlns:android="http://schemas.android.com/apk/res/android" <layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"> xmlns:app="http://schemas.android.com/apk/res-auto">
<ScrollView <FrameLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:id="@+id/root"> android:id="@+id/root">
<LinearLayout <ScrollView
android:orientation="vertical"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content"> android:layout_height="match_parent">
<ImageView
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="200dp"
android:padding="50dp"
app:srcCompat="@drawable/ic_app"
android:background="@color/defaultBrand" />
<LinearLayout <LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical"
android:padding="20dp"> android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText <FrameLayout
android:id="@+id/name_et"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="200dp">
android:ems="10" <org.osmdroid.views.MapView
android:hint="@string/name" android:id="@+id/map"
android:lines="1" android:layout_width="match_parent"
android:maxLines="1" android:layout_height="match_parent"
android:singleLine="true" android:focusable="false"
android:ellipsize="end"/> android:clickable="false"/>
<View
android:id="@+id/map_bt"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
<EditText <LinearLayout
android:id="@+id/description_et"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:ems="10" android:orientation="vertical"
android:gravity="start|top" android:padding="20dp">
android:inputType="textMultiLine"
android:lines="5"
android:maxLines="10"
android:hint="@string/description"
android:ellipsize="end" />
<TextView <EditText
android:layout_width="match_parent" android:id="@+id/name_et"
android:layout_height="wrap_content" android:layout_width="match_parent"
android:layout_marginTop="20dp" android:layout_height="wrap_content"
android:textStyle="bold" android:ems="10"
android:text="@string/created" /> android:hint="@string/name"
android:lines="1"
android:maxLines="1"
android:singleLine="true"
android:ellipsize="end"/>
<TextView <EditText
android:id="@+id/created_tv" android:id="@+id/description_et"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textAlignment="textEnd" /> android:ems="10"
android:gravity="start|top"
android:inputType="textMultiLine"
android:lines="5"
android:maxLines="10"
android:hint="@string/description"
android:ellipsize="end" />
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="20dp" android:layout_marginTop="20dp"
android:textStyle="bold" android:textStyle="bold"
android:text="@string/modified" /> android:text="@string/created" />
<TextView <TextView
android:id="@+id/modified_tv" android:id="@+id/created_tv"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textAlignment="textEnd" /> android:textAlignment="textEnd" />
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="20dp" android:layout_marginTop="20dp"
android:textStyle="bold" android:textStyle="bold"
android:text="@string/category" /> android:text="@string/modified" />
<TextView <TextView
android:id="@+id/category_tv" android:id="@+id/modified_tv"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textAlignment="textEnd" /> android:textAlignment="textEnd" />
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginTop="20dp" android:layout_marginTop="20dp"
android:text="@string/coords" android:textStyle="bold"
android:textStyle="bold" /> android:text="@string/category" />
<TextView <TextView
android:id="@+id/coords_tv" android:id="@+id/category_tv"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textAlignment="textEnd" /> android:textAlignment="textEnd" />
<TextView <TextView
android:id="@+id/accuracy_tv" android:layout_width="match_parent"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="wrap_content" android:layout_marginTop="20dp"
android:layout_marginTop="10dp" android:text="@string/coords"
android:textAlignment="center" android:textStyle="bold" />
android:text="@string/accuracy"
android:textColor="@android:color/white"
android:background="@android:color/darker_gray"/>
<Button <TextView
android:id="@+id/submit_bt" android:id="@+id/coords_tv"
style="@style/Widget.AppCompat.Button.Colored" android:layout_width="match_parent"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_height="60dp" android:textAlignment="textEnd" />
android:layout_margin="50dp"
android:text="@string/confirm" <TextView
app:backgroundTint="@color/defaultBrand" android:id="@+id/accuracy_tv"
android:onClick="onSubmit"/> android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:textAlignment="center"
android:text="@string/accuracy"
android:textColor="@android:color/white"
android:background="@android:color/darker_gray"/>
<Button
android:id="@+id/submit_bt"
style="@style/Widget.AppCompat.Button.Colored"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_margin="50dp"
android:text="@string/confirm"
app:backgroundTint="@color/defaultBrand"
android:onClick="onSubmit"/>
</LinearLayout>
</LinearLayout> </LinearLayout>
</ScrollView>
</LinearLayout> <!-- Back button -->
</ScrollView> <ImageView
android:id="@+id/back_bt"
android:layout_width="48dp"
android:layout_height="48dp"
android:padding="12dp"
android:src="@drawable/ic_back_grey"
app:tint="@color/white"
android:background="@color/defaultBrandAlpha"/>
</FrameLayout>
</layout> </layout>

View File

@ -22,9 +22,13 @@
<color name="accent">#121212</color> <color name="accent">#121212</color>
<color name="transparent">#00000000</color> <color name="transparent">#00000000</color>
<color name="defaultBrand">#0082C9</color> <color name="defaultBrand">#0082C9</color>
<color name="defaultBrandAlpha">#550082C9</color>
<color name="appbar">@android:color/white</color> <color name="appbar">@android:color/white</color>
<color name="defaultTint">#202124</color> <color name="defaultTint">#202124</color>
<!-- List Colors --> <!-- List Colors -->
<color name="list_text">#aaa</color> <color name="list_text">#aaa</color>
<!-- Generic Colors -->
<color name="white">#fff</color>
</resources> </resources>

View File

@ -25,7 +25,7 @@ buildscript {
jcenter() jcenter()
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:7.0.2' classpath 'com.android.tools.build:gradle:4.2.2'
// NOTE: Do not place your application dependencies here; they belong // NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files // in the individual module build.gradle files

BIN
screenshots/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

BIN
screenshots/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB