-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathInclinometerFragment.java
More file actions
140 lines (114 loc) · 4.86 KB
/
InclinometerFragment.java
File metadata and controls
140 lines (114 loc) · 4.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package io.github.iso53.nothingcompass.fragment;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;
import io.github.iso53.nothingcompass.R;
import io.github.iso53.nothingcompass.preference.PreferenceStore;
import io.github.iso53.nothingcompass.view.InclinometerView;
import io.github.iso53.nothingcompass.view.LevelMeterView;
public class InclinometerFragment extends Fragment implements SensorEventListener {
private static final float TRANSITION_THRESHOLD = 0.5f; // gz threshold for switching views
private static final long ANIMATION_DURATION = 300; // milliseconds
private SensorManager sensorManager;
private Sensor gravitySensor;
private InclinometerView inclinometerView;
private LevelMeterView levelMeterView;
private PreferenceStore preferenceStore;
private boolean isInclinometerVisible = true;
public InclinometerFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_inclinometer, container, false);
inclinometerView = v.findViewById(R.id.inclinometerView);
levelMeterView = v.findViewById(R.id.levelMeterView);
sensorManager = (SensorManager) requireContext().getSystemService(Context.SENSOR_SERVICE);
gravitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
preferenceStore = new PreferenceStore(requireContext(), getViewLifecycleOwner().getLifecycle());
preferenceStore.getHapticFeedback().observe(getViewLifecycleOwner(), enabled -> {
inclinometerView.setHapticFeedbackEnabled(enabled);
levelMeterView.setHapticFeedbackEnabled(enabled);
});
preferenceStore.getHighPrecision().observe(getViewLifecycleOwner(), enabled -> {
levelMeterView.setHighPrecisionEnabled(enabled);
});
// Initially show inclinometer, hide level meter
inclinometerView.setAlpha(1f);
inclinometerView.setIsActive(true);
levelMeterView.setAlpha(0f);
levelMeterView.setIsActive(false);
return v;
}
@Override
public void onResume() {
super.onResume();
sensorManager.registerListener(this, gravitySensor, SensorManager.SENSOR_DELAY_GAME);
}
@Override
public void onPause() {
super.onPause();
sensorManager.unregisterListener(this);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@Override
public void onSensorChanged(SensorEvent e) {
float gx = e.values[0];
float gy = e.values[1];
float gz = e.values[2];
// Normalize gravity vector
float norm = (float) Math.sqrt(gx * gx + gy * gy + gz * gz);
gx /= norm;
gy /= norm;
gz /= norm;
// Determine which view should be visible based on device orientation
// |gz| close to 1 = device is flat (show inclinometer)
// |gz| close to 0 = device is upright (show level meter)
boolean shouldShowInclinometer = Math.abs(gz) > TRANSITION_THRESHOLD;
// Animate transition if orientation changed
if (shouldShowInclinometer != isInclinometerVisible) {
isInclinometerVisible = shouldShowInclinometer;
animateViewTransition(shouldShowInclinometer);
}
// Update both views (they'll only draw if visible)
float roll = -gx; // left/right tilt
float pitch = gy; // forward/back tilt
inclinometerView.updateTilt(pitch, roll);
levelMeterView.updateTilt(gx, gy);
}
private void animateViewTransition(boolean showInclinometer) {
if (showInclinometer) {
// Fade in inclinometer, fade out level meter
inclinometerView.animate()
.alpha(1f)
.setDuration(ANIMATION_DURATION)
.start();
inclinometerView.setIsActive(true);
levelMeterView.animate()
.alpha(0f)
.setDuration(ANIMATION_DURATION)
.start();
levelMeterView.setIsActive(false);
} else {
// Fade out inclinometer, fade in level meter
inclinometerView.animate()
.alpha(0f)
.setDuration(ANIMATION_DURATION)
.start();
inclinometerView.setIsActive(false);
levelMeterView.animate()
.alpha(1f)
.setDuration(ANIMATION_DURATION)
.start();
levelMeterView.setIsActive(true);
}
}
}