Feat: Added batter status widget.
Signed-off-by: HeCodes2Much <wayne6324@gmail.com>
This commit is contained in:
@@ -24,16 +24,6 @@ android {
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
manifestPlaceholders["internetPermission"] = "android.permission.INTERNET"
|
||||
|
||||
val weatherFile = project.rootProject.file("weather.properties")
|
||||
val properties = Properties()
|
||||
properties.load(weatherFile.inputStream())
|
||||
val apiKey = properties.getProperty("WEATHER_API_KEY") ?: ""
|
||||
buildConfigField(
|
||||
type = "String",
|
||||
name = "API_KEY",
|
||||
value = "\"$apiKey\""
|
||||
)
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
@@ -82,14 +72,26 @@ android {
|
||||
productFlavors {
|
||||
create("withInternet") {
|
||||
dimension = "internet"
|
||||
manifestPlaceholders["hasInternetPermission"] = true
|
||||
manifestPlaceholders["internetPermission"] = "android.permission.INTERNET"
|
||||
val weatherFile = project.rootProject.file("weather.properties")
|
||||
val properties = Properties()
|
||||
properties.load(weatherFile.inputStream())
|
||||
val apiKey = properties.getProperty("WEATHER_API_KEY") ?: ""
|
||||
buildConfigField(
|
||||
type = "String",
|
||||
name = "API_KEY",
|
||||
value = "\"$apiKey\""
|
||||
)
|
||||
}
|
||||
|
||||
create("withoutInternet") {
|
||||
dimension = "internet"
|
||||
manifestPlaceholders["hasInternetPermission"] = false
|
||||
manifestPlaceholders["internetPermission"] = "REMOVE"
|
||||
buildConfigField(
|
||||
type = "String",
|
||||
name = "API_KEY",
|
||||
value = "\"REMOVE\""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import android.text.style.StyleSpan
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.core.text.getSpans
|
||||
import java.util.Locale
|
||||
|
||||
/**
|
||||
* Returns [Spannable] where the term is
|
||||
@@ -101,4 +102,8 @@ fun String.showLongToast(context: Context) {
|
||||
|
||||
fun String.showShortToast(context: Context) {
|
||||
Toast.makeText(context, this, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
fun String.capitalizeEachWord(): String {
|
||||
return this.split(" ").joinToString(" ") { it.replaceFirstChar { str -> if (str.isLowerCase()) str.titlecase(Locale.getDefault()) else str.toString() } }
|
||||
}
|
||||
@@ -257,13 +257,11 @@ class AppHelper @Inject constructor() {
|
||||
): WeatherResponse {
|
||||
// Check if cached data is available and not expired
|
||||
val cachedWeatherData = context.getWeatherDataFromCache()
|
||||
if (cachedWeatherData != null && System.currentTimeMillis() - cachedWeatherData.timestamp < TimeUnit.MINUTES.toMillis(
|
||||
5
|
||||
)
|
||||
) {
|
||||
if (cachedWeatherData?.let { System.currentTimeMillis() - it.timestamp < TimeUnit.MINUTES.toMillis(15) } == true) {
|
||||
return cachedWeatherData.weatherResponse
|
||||
}
|
||||
|
||||
|
||||
// Fetch weather data from the network
|
||||
val apiKey = BuildConfig.API_KEY
|
||||
val units = "metric"
|
||||
@@ -306,8 +304,8 @@ class AppHelper @Inject constructor() {
|
||||
|
||||
// Function to retrieve weather data from cache
|
||||
private fun Context.getWeatherDataFromCache(): CachedWeatherData? {
|
||||
val sharedPreferences = getSharedPreferences("WeatherCache", Context.MODE_PRIVATE)
|
||||
val timestamp = sharedPreferences.getLong("timestamp", -1)
|
||||
val sharedPreferences = getSharedPreferences(Constants.WEATHER_PREFS, Context.MODE_PRIVATE)
|
||||
val timestamp = sharedPreferences.getLong("cachedDataTimestamp", -1)
|
||||
val weatherResponseJson = sharedPreferences.getString("weatherResponse", null)
|
||||
if (timestamp != -1L && weatherResponseJson != null) {
|
||||
val weatherResponse = Gson().fromJson(weatherResponseJson, WeatherResponse::class.java)
|
||||
|
||||
@@ -28,5 +28,7 @@ data class Weather(
|
||||
)
|
||||
|
||||
data class Sys(
|
||||
val country: String
|
||||
val country: String,
|
||||
val sunrise: Int,
|
||||
val sunset: Int
|
||||
)
|
||||
@@ -1,22 +1,30 @@
|
||||
package com.github.droidworksstudio.launcher.ui.widgets
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Paint
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.os.BatteryManager
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.res.ResourcesCompat
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import com.github.droidworksstudio.common.capitalizeEachWord
|
||||
import com.github.droidworksstudio.common.hasInternetPermission
|
||||
import com.github.droidworksstudio.common.hideKeyboard
|
||||
import com.github.droidworksstudio.launcher.R
|
||||
import com.github.droidworksstudio.launcher.databinding.FragmentWidgetsBinding
|
||||
@@ -27,7 +35,10 @@ import com.github.droidworksstudio.launcher.listener.ScrollEventListener
|
||||
import com.github.droidworksstudio.launcher.utils.Constants
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.launch
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Calendar
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
@@ -52,7 +63,6 @@ class WidgetFragment : Fragment(),
|
||||
): View {
|
||||
// Inflate the layout for this fragment
|
||||
_binding = FragmentWidgetsBinding.inflate(inflater, container, false)
|
||||
_binding = binding
|
||||
|
||||
return binding.root
|
||||
}
|
||||
@@ -65,6 +75,7 @@ class WidgetFragment : Fragment(),
|
||||
|
||||
initializeInjectedDependencies()
|
||||
setupWeatherWidget()
|
||||
setupBatteryWidget()
|
||||
observeSwipeTouchListener()
|
||||
observeClickListener()
|
||||
}
|
||||
@@ -72,7 +83,7 @@ class WidgetFragment : Fragment(),
|
||||
private fun initializeInjectedDependencies() {
|
||||
context = requireContext()
|
||||
binding.nestScrollView.hideKeyboard()
|
||||
|
||||
//
|
||||
binding.nestScrollView.scrollEventListener = this
|
||||
}
|
||||
|
||||
@@ -81,29 +92,35 @@ class WidgetFragment : Fragment(),
|
||||
context.getSharedPreferences(Constants.WEATHER_PREFS, Context.MODE_PRIVATE)
|
||||
val latitude = sharedPreferences.getFloat(Constants.LATITUDE, 0f)
|
||||
val longitude = sharedPreferences.getFloat(Constants.LONGITUDE, 0f)
|
||||
val timestamp = convertTimestampToReadableDate(sharedPreferences.getLong("cachedDataTimestamp", 0))
|
||||
|
||||
lifecycleScope.launch {
|
||||
try {
|
||||
if (!context.hasInternetPermission()) return@launch
|
||||
binding.weatherRoot.visibility = View.VISIBLE
|
||||
val weatherResponse = appHelper.fetchWeatherData(context, latitude, longitude)
|
||||
Log.d("weatherResponse", "$weatherResponse")
|
||||
val temperatureScale = if (preferenceHelper.weatherUnits == Constants.Units.Metric) getString(R.string.weather_c) else getString(
|
||||
R.string.weather_f
|
||||
val temperatureScale = if (preferenceHelper.weatherUnits == Constants.Units.Metric) getString(R.string.widget_c) else getString(
|
||||
R.string.widget_f
|
||||
)
|
||||
val speedScale = if (preferenceHelper.weatherUnits == Constants.Units.Metric) getString(R.string.weather_mps) else getString(R.string.weather_mph)
|
||||
val speedScale = if (preferenceHelper.weatherUnits == Constants.Units.Metric) getString(R.string.widget_weather_mps) else getString(R.string.widget_weather_mph)
|
||||
|
||||
binding.weatherCity.setTextColor(preferenceHelper.widgetTextColor)
|
||||
binding.weatherTemperature.setTextColor(preferenceHelper.widgetTextColor)
|
||||
binding.weatherDescription.setTextColor(preferenceHelper.widgetTextColor)
|
||||
binding.weatherWind.setTextColor(preferenceHelper.widgetTextColor)
|
||||
binding.weatherHumidity.setTextColor(preferenceHelper.widgetTextColor)
|
||||
binding.weatherPressure.setTextColor(preferenceHelper.widgetTextColor)
|
||||
binding.weatherRefresh.setTextColor(preferenceHelper.widgetTextColor)
|
||||
binding.weatherLastRun.setTextColor(preferenceHelper.widgetTextColor)
|
||||
binding.weatherRefresh.typeface = ResourcesCompat.getFont(requireActivity(), R.font.weather)
|
||||
|
||||
binding.weatherCity.text = getString(R.string.widget_weather_location, weatherResponse.name, weatherResponse.sys.country)
|
||||
binding.weatherTemperature.text = getString(R.string.widget_weather_temp, weatherResponse.main.temp, temperatureScale)
|
||||
binding.weatherDescription.text = getString(R.string.widget_weather_description, weatherResponse.weather[0].description)
|
||||
binding.weatherDescription.text = getString(R.string.widget_weather_description, weatherResponse.weather[0].description).capitalizeEachWord()
|
||||
binding.weatherWind.text = getString(R.string.widget_weather_wind, weatherResponse.wind.speed, speedScale)
|
||||
binding.weatherHumidity.text = getString(R.string.widget_weather_humidity, weatherResponse.main.humidity)
|
||||
binding.weatherPressure.text = getString(R.string.widget_weather_pressure, weatherResponse.main.pressure)
|
||||
binding.weatherLastRun.text = timestamp
|
||||
binding.weatherRefresh.text = getString(R.string.widget_weather_refresh, getString(R.string.refresh_icon))
|
||||
|
||||
val weatherIcon = createWeatherIcon(context, setWeatherIcon(context, weatherResponse.weather[0].id))
|
||||
binding.weatherIcon.setImageBitmap(weatherIcon)
|
||||
@@ -112,10 +129,7 @@ class WidgetFragment : Fragment(),
|
||||
if (weatherWidgetDrawable is GradientDrawable) {
|
||||
weatherWidgetDrawable.setColor(preferenceHelper.widgetBackgroundColor)
|
||||
}
|
||||
|
||||
binding.weatherButtonRefresh.setColorFilter(preferenceHelper.widgetTextColor)
|
||||
} catch (e: Exception) {
|
||||
binding.weatherRoot.visibility = View.GONE
|
||||
Log.e("Weather", "Failed to fetch weather data: ${e.message}")
|
||||
}
|
||||
}
|
||||
@@ -138,10 +152,10 @@ class WidgetFragment : Fragment(),
|
||||
}
|
||||
|
||||
private fun setWeatherIcon(context: Context, id: Int): String {
|
||||
var icon = ""
|
||||
val icon: String
|
||||
val idDivided = id / 100
|
||||
val hourOfDay = Calendar.getInstance().get(Calendar.HOUR_OF_DAY)
|
||||
if (idDivided * 100 == 800) {
|
||||
val hourOfDay = Calendar.getInstance().get(Calendar.HOUR_OF_DAY)
|
||||
icon = if (hourOfDay in 7..19) {
|
||||
context.getString(R.string.weather_sunny)
|
||||
} else {
|
||||
@@ -161,6 +175,70 @@ class WidgetFragment : Fragment(),
|
||||
return icon
|
||||
}
|
||||
|
||||
private fun convertTimestampToReadableDate(timestamp: Long): String {
|
||||
val date = Date(timestamp)
|
||||
val format = SimpleDateFormat("hh:mm aa", Locale.getDefault())
|
||||
return format.format(date)
|
||||
}
|
||||
|
||||
private fun setupBatteryWidget() {
|
||||
try {
|
||||
binding.batteryLevel.setTextColor(preferenceHelper.widgetTextColor)
|
||||
binding.chargingStatus.setTextColor(preferenceHelper.widgetTextColor)
|
||||
binding.batteryHealth.setTextColor(preferenceHelper.widgetTextColor)
|
||||
binding.batteryVoltage.setTextColor(preferenceHelper.widgetTextColor)
|
||||
binding.batteryTemperature.setTextColor(preferenceHelper.widgetTextColor)
|
||||
|
||||
val weatherBatteryDrawable = binding.batteryRoot.background
|
||||
if (weatherBatteryDrawable is GradientDrawable) {
|
||||
weatherBatteryDrawable.setColor(preferenceHelper.widgetBackgroundColor)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e("Battery", "Failed to fetch battery data: ${e.message}")
|
||||
}
|
||||
binding.batteryRoot.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
private val batteryReceiver = object : BroadcastReceiver() {
|
||||
@RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
if (intent?.action == Intent.ACTION_BATTERY_CHANGED) {
|
||||
val level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
|
||||
val scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
|
||||
val isCharging = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1)
|
||||
val health = intent.getIntExtra(BatteryManager.EXTRA_HEALTH, BatteryManager.BATTERY_HEALTH_UNKNOWN)
|
||||
val count = intent.getIntExtra(BatteryManager.EXTRA_CYCLE_COUNT, 0)
|
||||
val voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, 0)
|
||||
val temperature = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0)
|
||||
|
||||
val voltageScale = getString(R.string.widget_mv)
|
||||
val temperatureScale = getString(R.string.widget_c)
|
||||
|
||||
val batteryPct = (level / scale.toFloat() * 100).toInt()
|
||||
val chargingStatusText = when (isCharging) {
|
||||
BatteryManager.BATTERY_PLUGGED_AC, BatteryManager.BATTERY_PLUGGED_USB, BatteryManager.BATTERY_PLUGGED_WIRELESS -> "Charging"
|
||||
else -> "Not Charging"
|
||||
}
|
||||
val healthStatus = when (health) {
|
||||
BatteryManager.BATTERY_HEALTH_GOOD -> "Good"
|
||||
BatteryManager.BATTERY_HEALTH_OVERHEAT -> "Overheat"
|
||||
BatteryManager.BATTERY_HEALTH_DEAD -> "Dead"
|
||||
BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE -> "Over Voltage"
|
||||
BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE -> "Unspecified Failure"
|
||||
BatteryManager.BATTERY_HEALTH_COLD -> "Cold"
|
||||
else -> "Unknown"
|
||||
}
|
||||
|
||||
binding.batteryLevel.text = getString(R.string.widgets_battery_level, batteryPct)
|
||||
binding.batteryCount.text = getString(R.string.widgets_battery_count, count)
|
||||
binding.chargingStatus.text = getString(R.string.widgets_battery_status, chargingStatusText)
|
||||
binding.batteryHealth.text = getString(R.string.widgets_battery_health, healthStatus)
|
||||
binding.batteryVoltage.text = getString(R.string.widgets_battery_voltage, voltage, voltageScale)
|
||||
binding.batteryTemperature.text = getString(R.string.widgets_battery_temperature, temperature, temperatureScale)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
private fun observeSwipeTouchListener() {
|
||||
@@ -183,9 +261,20 @@ class WidgetFragment : Fragment(),
|
||||
}
|
||||
|
||||
private fun observeClickListener() {
|
||||
binding.weatherButtonRefresh.setOnClickListener {
|
||||
binding.weatherRefresh.setOnClickListener {
|
||||
setupWeatherWidget()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
context.registerReceiver(batteryReceiver, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
|
||||
setupWeatherWidget()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
context.unregisterReceiver(batteryReceiver)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<solid android:color="#ffffff" />
|
||||
<corners android:radius="8dp" />
|
||||
<corners android:radius="10dp" />
|
||||
<padding
|
||||
android:left="16dp"
|
||||
android:top="16dp"
|
||||
android:right="16dp"
|
||||
android:bottom="16dp" />
|
||||
android:left="14dp"
|
||||
android:top="10dp"
|
||||
android:right="14dp"
|
||||
android:bottom="10dp" />
|
||||
</shape>
|
||||
|
||||
@@ -19,132 +19,227 @@
|
||||
android:id="@+id/nestScrollView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fillViewport="true"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:clipChildren="false"
|
||||
android:clipToPadding="false"
|
||||
android:fadingEdgeLength="48dp"
|
||||
android:fillViewport="true"
|
||||
android:overScrollMode="never"
|
||||
android:requiresFadingEdge="vertical"
|
||||
android:scrollbars="none">
|
||||
android:scrollbars="none"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:ignore="SpeakableTextPresentCheck">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/weather_root"
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:orientation="vertical"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="24dp"
|
||||
android:layout_marginVertical="50dp"
|
||||
android:background="@drawable/widget_background">
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
<RelativeLayout
|
||||
android:id="@+id/weather_root"
|
||||
android:layout_width="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:id="@+id/topHeader"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/weather_city"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="2"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:lines="1"
|
||||
android:textSize="18sp"
|
||||
tools:text="Kayamkulam, IN" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/weather_button_refresh"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:background="@android:color/transparent"
|
||||
android:contentDescription="@string/widget_weather_refresh"
|
||||
android:src="@drawable/icon_refresh" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:layout_below="@id/topHeader"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingEnd="8dp"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingRight="8dp"
|
||||
android:paddingStart="8dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/weather_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical|center_horizontal"
|
||||
android:layout_marginEnd="18dp"
|
||||
android:layout_weight="0.3"
|
||||
android:contentDescription="@string/widget_weather_description" />
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:layout_marginVertical="5dp"
|
||||
android:background="@drawable/widget_background"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:id="@+id/topHeaderWeather"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0.7"
|
||||
android:orientation="vertical">
|
||||
android:layout_alignParentStart="true"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/weather_temperature"
|
||||
android:id="@+id/weather_city"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="3"
|
||||
android:ellipsize="end"
|
||||
android:textAlignment="viewStart"
|
||||
android:gravity="start"
|
||||
android:lines="1"
|
||||
android:text="@string/widget_weather_temp"
|
||||
android:textSize="30sp" />
|
||||
android:textSize="16sp"
|
||||
tools:text="London, GB" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/weather_description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/weather_lastRun"
|
||||
android:layout_width="115dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginEnd="2dp"
|
||||
android:layout_weight="2"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical|end"
|
||||
android:lines="1"
|
||||
android:paddingTop="2dp"
|
||||
android:text="@string/widget_weather_description"
|
||||
android:textSize="16sp" />
|
||||
android:textSize="11sp"
|
||||
tools:text="lastRun" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/weather_wind"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/weather_refresh"
|
||||
android:layout_width="42dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="end"
|
||||
android:paddingTop="2dp"
|
||||
android:text="@string/widget_weather_wind"
|
||||
android:lines="1" />
|
||||
android:gravity="end"
|
||||
android:lines="1"
|
||||
android:textSize="18sp"
|
||||
tools:text="refresh" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/weather_humidity"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:paddingTop="2dp"
|
||||
android:text="@string/widget_weather_humidity"
|
||||
android:lines="1" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/weather_pressure"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="2dp"
|
||||
android:ellipsize="end"
|
||||
android:text="@string/widget_weather_pressure"
|
||||
android:lines="1" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/topHeaderWeather"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:paddingRight="8dp">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/weather_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center_vertical|center_horizontal"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:layout_weight="0.3"
|
||||
android:contentDescription="@string/widget_weather_description" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="0.7"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/weather_temperature"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:lines="1"
|
||||
android:paddingTop="2dp"
|
||||
android:text="@string/widget_weather_temp"
|
||||
android:textSize="20sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/weather_description"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:lines="1"
|
||||
android:paddingTop="2dp"
|
||||
android:text="@string/widget_weather_description"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/weather_wind"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:lines="1"
|
||||
android:paddingTop="2dp"
|
||||
android:text="@string/widget_weather_wind"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/weather_humidity"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:lines="1"
|
||||
android:paddingTop="2dp"
|
||||
android:text="@string/widget_weather_humidity"
|
||||
android:textSize="14sp" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/battery_root"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="16dp"
|
||||
android:layout_marginVertical="5dp"
|
||||
android:background="@drawable/widget_background"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/topHeaderBattery"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
android:orientation="vertical"
|
||||
tools:ignore="UselessParent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/battery_level"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:lines="1"
|
||||
android:paddingTop="2dp"
|
||||
android:text="@string/widgets_battery_level"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/battery_count"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:lines="1"
|
||||
android:paddingTop="2dp"
|
||||
android:text="@string/widgets_battery_count"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/charging_status"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:lines="1"
|
||||
android:paddingTop="2dp"
|
||||
android:text="@string/widgets_battery_status"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/battery_health"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:lines="1"
|
||||
android:paddingTop="2dp"
|
||||
android:text="@string/widgets_battery_health"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/battery_voltage"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:lines="1"
|
||||
android:paddingTop="2dp"
|
||||
android:text="@string/widgets_battery_voltage"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/battery_temperature"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:lines="1"
|
||||
android:paddingTop="2dp"
|
||||
android:text="@string/widgets_battery_temperature"
|
||||
android:textSize="14sp" />
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
</LinearLayout>
|
||||
|
||||
</com.github.droidworksstudio.launcher.view.GestureNestedScrollView>
|
||||
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/widget_frame"
|
||||
android:padding="8dp"/>
|
||||
@@ -1,17 +1,18 @@
|
||||
<resources>
|
||||
<string name="battery_level" translatable="false">%s%%</string>
|
||||
<string name="widget_mv" translatable="false">mV</string>
|
||||
|
||||
|
||||
<string name="widget_c" translatable="false">°C</string>
|
||||
<string name="widget_f" translatable="false">°F</string>
|
||||
|
||||
<string name="widget_weather_refresh" translatable="false">%1$s</string>
|
||||
<string name="widget_weather_location" translatable="false">%1$s, %2$s</string>
|
||||
<string name="widget_weather_temp" translatable="false">%1$.2f %2$s</string>
|
||||
<string name="widget_weather_temp" translatable="false">%1$.0f %2$s</string>
|
||||
<string name="widget_weather_description" translatable="false">%1$s</string>
|
||||
|
||||
<string name="weather_mps" translatable="false">m/s</string>
|
||||
<string name="weather_mph" translatable="false">mil/h</string>
|
||||
<string name="weather_mm" translatable="false">mm</string>
|
||||
|
||||
<string name="weather_c" translatable="false">°C</string>
|
||||
<string name="weather_f" translatable="false">°F</string>
|
||||
<string name="widget_weather_mps" translatable="false">m/s</string>
|
||||
<string name="widget_weather_mph" translatable="false">mil/h</string>
|
||||
|
||||
<string name="widget_weather_feels_like" translatable="false">Feels Like : %s%</string>
|
||||
<string name="widget_weather_wind" translatable="false">Wind : %1$.2f %2$s</string>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<!-- Strings used for fragments header labels -->
|
||||
<string name="favorite_fragment_name">Favorite Apps</string>
|
||||
<string name="hidden_fragment_name">Hidden Apps</string>
|
||||
|
||||
|
||||
<string name="search">Search</string>
|
||||
|
||||
<string name="bottom_dialog_app_rename">Rename</string>
|
||||
@@ -595,4 +595,13 @@
|
||||
<string name="search_bing">Bing</string>
|
||||
<string name="search_brave">Brave</string>
|
||||
<string name="search_swisscow">SwissCows</string>
|
||||
|
||||
<string name="widgets_battery_level">Battery Level : %d %%</string>
|
||||
<string name="widgets_battery_count">Battery Charge Count : %1$d</string>
|
||||
<string name="widgets_battery_status">Charging Status : %1$s</string>
|
||||
<string name="widgets_battery_health">Battery Health : %1$s</string>
|
||||
<string name="widgets_battery_voltage">Battery Voltage : %1$d %2$s</string>
|
||||
<string name="widgets_battery_temperature">Battery Temperature : %1$d %2$s</string>
|
||||
|
||||
|
||||
</resources>
|
||||
@@ -1,5 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="refresh_icon" translatable="false"></string>
|
||||
|
||||
<string name="humidity_icon" translatable="false"></string>
|
||||
<string name="pressure_icon" translatable="false"></string>
|
||||
<string name="speed_icon" translatable="false"></string>
|
||||
@@ -14,6 +16,4 @@
|
||||
<string name="weather_snowy" translatable="false"></string>
|
||||
<string name="weather_thunder" translatable="false"></string>
|
||||
<string name="weather_drizzle" translatable="false"></string>
|
||||
<string name="rain" translatable="false"></string>
|
||||
<string name="snow" translatable="false"></string>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user