مستندات جامع اندروید
نسخه 1.0.3
هدف این بخش از پروژه تغییر زاویه (یا شیب) دوربین است. تغییر شیب دوربین در ایجاد حالت navigation یا برای مشاهده ساختمانهای سهبعدی کاربرد دارد.
activity_tilt_camera.xml
:
در فایل لیاوت این بخش از پروژه، علاوه بر المان نقشه نشان، یک LinearLayout
وجود دارد که در آن یک SeekBar
وجود دارد که برای تنظیم میزان شیب به کار میرود. نکتهای که در SeekBar
وجود دارد این است که میزان مینیمم و ماکزیمم آن به ترتیب ۰ و ۶۰ است در حالی که همانطور که گفته شد این میزان برای نقشه نشان برابر با ۳۰ و ۹۰ است، پس در طول برنامه برای استفاده از مقداری که این SeekBar
مشخص میکند، آن مقدار را با ۳۰ جمع میکنیم.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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"
tools:context=".activity.TiltCameraActivity">
<org.neshan.mapsdk.MapView
android:id="@+id/mapview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ToggleButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:background="@drawable/toggle_button_bg"
android:checked="true"
android:elevation="8dp"
android:onClick="toggleCameraTilt"
android:paddingStart="8dp"
android:paddingEnd="8dp"
android:textColor="@color/white"
android:textOff="تغییر زاویه دوربین"
android:textOn="تغییر زاویه دوربین"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:targetApi="m" />
<LinearLayout
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_marginStart="32dp"
android:layout_marginTop="32dp"
android:layout_marginEnd="32dp"
android:background="@drawable/rounded_white_bg"
android:gravity="center"
android:orientation="horizontal"
android:padding="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="۳۰ درجه"
android:textColor="@color/black" />
<!--it is not possible to set min range for seek bar (default value = 0)-->
<!--so we get seek bar range 0-60 (camera tilt range in neshan is 30-90)-->
<!--and add 30 to every read value of seek bar-->
<SeekBar
android:id="@+id/tilt_seek_bar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginEnd="4dp"
android:layout_weight="99"
android:max="60"
android:progress="60"
android:progressDrawable="@drawable/seek_bar_bg"
android:thumb="@drawable/seek_bar_thumb" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="۹۰ درجه"
android:textColor="@color/black" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
TiltCameraActivity.kt
:
متد initLayoutRefrences
جهت مقداردهی اولیه کردن به تمامی المانهای مربوط به رابط کاربری نوشته شدهاست. به دلیل این که لازم است تا المان اندرویدی نقشه نشان ابتدا به طور کامل ایجاد شود و سپس با آن تعامل برقرار شود (متدهای مختلف بر روی المان نقشه اجرا شود)، تمامی متدهای مربوط به رابط کاربری باید در متد onStart
انجام شوند.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_draw_polygon)
}
override fun onStart() {
super.onStart()
// everything related to ui is initialized here
initLayoutReferences()
}
در اینجا بر روی tiltSeekBar
یک OnSeekBarChangeListener
ست شده است. هرگاه متد onProgressChanged
صدا زده شود، مقدار progress
را با عدد ۳۰ جمع کرده (به دلیلی که در بالاتر توضیح داده شد) و این مقدار را به عنوان مقدار فیلد tilt
که بر روی map
صدا زده میشود داده میشود.
متد tilt
میزان زاویه (یا شیب) نقشه را تنظیم میکند.
ممکن است کاربر بدون استفاده از tiltSeekBar
و با استفاده از دو انگشت و با gesture های از پیش تعریف شده بر روی نقشه، میزان زاویه را تغییر دهد. برای این که بعد از تغییر در اینحالت، progress
نشان دادهشده بر روی tiltSeekBar
نیز مقدار درستی داشته باشد، یک OnCameraMoveListener
برای تشخیص تغییر دوربین به map ست میشود و در هنگام حرکت نقشه، میزان زاویه نقشه گرفته شده، ۳۰ واحد از آن کممیشود، به بالا گرد میشود و به فیلد progress
– که بر روی tiltSeekBar
وجود دارد – داده میشود.
در متد onMapMoved
، همین متد بر روی super
نیز صدا زده میشود تا عملیاتی که در SDK برای زمانی که نقشه حرکت میکند پیادهسازی شده است نیز انجام شود.
برای بهروزرسانی میزان پیشرفت نشانداده شده بر روی SeekBar
موجود در رابط کاربری، بهتر است نخ جدیدی در رابط کاربری ایجاد کرده و این کار را به جای این که در نخی که نقشه در آن وجود دارد، در نخ جدید انجام دهیم. دلیل این کار این است که عملیات مربوط به نمایش نقشه، عملیات سنگینی است و در صورتی که بخواهیم تغییرات دیگر عناصر رابط کاربری را نیز در این نخ انجام دهیم، ممکن است بهروزرسانیهای نقشه یا دیگر المانهای رابط کاربری به درستی انجام نشود. برای ایجاد یک نخ رابطکاربری جدید، متد runOnUiThread
را صدا زده، یک شی Runnable
جدید ایجاد کرده، تابع run
را Override کرده و عملیاتی که برای آپدیت دیگر المانهای رابط کاربری باید انجام شود را در این متد مینویسیم.
// Initializing layout references (views, map and map events)
private fun initLayoutReferences() {
// Initializing views
initViews()
// Initializing mapView element
initMap()
//tilt camera
seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(p0: SeekBar?, p1: Int, p2: Boolean) {
map.setTilt(seekBar.progress + 30f, 0f)
}
override fun onStartTrackingTouch(p0: SeekBar?) {
}
override fun onStopTrackingTouch(p0: SeekBar?) {
Log.d("asd", seekBar.progress.toString());
}
})
map.setOnCameraMoveListener {
runOnUiThread {
seekBar.progress = Math.round(map.tilt) - 30
}
}
}
هنگامی که ToggleButton
موجود در رابط کاربری، در حالت انتخاب شده باشد، با استفاده از شی Settings
که یکی از فیلدهای المان نقشه است و مقداردهی فیلدهای minTiltAngle
و maxTiltAngle
بر روی آن، حداقل و حداکثر بازه تنظیم شیب نقشه بین ۳۰ درجه تا ۹۰ درجه (تمام مقدار ممکن) انتخاب میشود. در صورتی که ToggleButton
انتخاب نشده باشد، حداقل و حداکثر بازه تنظیم برابر با درجه فعلی شیب نقشه قرار میگیرد و در این صورت امکان تغییر شیب وجود نخواهد داشت.
fun toggleCameraTilt(view: View) {
val toggleButton = view as ToggleButton
if (toggleButton.isChecked) {
//set tilt range from 30 to 90 degrees
map.settings.minTiltAngle = 30f
map.settings.maxTiltAngle = 90f
} else {
//set tilt range to 1 degree (only current tilt degree)
map.settings.minTiltAngle = map.tilt
map.settings.maxTiltAngle = map.tilt
}
}