forked from github/wulkanowy-mirror
Timetable widget refactor (#171)
This commit is contained in:
parent
70879945f2
commit
7f6f632b73
@ -160,7 +160,6 @@
|
||||
<option name="KEEP_BLANK_LINES_IN_CODE" value="1" />
|
||||
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="0" />
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS" value="false" />
|
||||
<option name="METHOD_PARAMETERS_WRAP" value="5" />
|
||||
<option name="METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE" value="true" />
|
||||
<option name="METHOD_PARAMETERS_RPAREN_ON_NEXT_LINE" value="true" />
|
||||
<option name="EXTENDS_LIST_WRAP" value="1" />
|
||||
@ -171,4 +170,4 @@
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
||||
</component>
|
@ -47,6 +47,20 @@
|
||||
<action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
<service
|
||||
android:name=".services.widgets.TimetableWidgetService"
|
||||
android:permission="android.permission.BIND_REMOTEVIEWS" />
|
||||
|
||||
<receiver
|
||||
android:name=".ui.widgets.timetable.TimetableWidgetProvider"
|
||||
android:label="@string/timetable_title">
|
||||
<intent-filter>
|
||||
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
|
||||
</intent-filter>
|
||||
<meta-data
|
||||
android:name="android.appwidget.provider"
|
||||
android:resource="@xml/provider_widget_timetable" />
|
||||
</receiver>
|
||||
|
||||
<meta-data
|
||||
android:name="io.fabric.ApiKey"
|
||||
|
@ -1,5 +1,6 @@
|
||||
package io.github.wulkanowy.data.db
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.SharedPreferences
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
@ -7,19 +8,18 @@ import javax.inject.Singleton
|
||||
@Singleton
|
||||
class SharedPrefHelper @Inject constructor(private val sharedPref: SharedPreferences) {
|
||||
|
||||
fun putLong(key: String, value: Long) {
|
||||
sharedPref.edit().putLong(key, value).apply()
|
||||
@SuppressLint("ApplySharedPref")
|
||||
fun putLong(key: String, value: Long, sync: Boolean = false) {
|
||||
sharedPref.edit().putLong(key, value).apply {
|
||||
if (sync) commit() else apply()
|
||||
}
|
||||
}
|
||||
|
||||
fun getLong(key: String, defaultValue: Long): Long {
|
||||
return sharedPref.getLong(key, defaultValue)
|
||||
}
|
||||
|
||||
fun getBoolean(key: String, defaultValue: Boolean): Boolean {
|
||||
return sharedPref.getBoolean(key, defaultValue)
|
||||
}
|
||||
|
||||
fun getString(key: String, defaultValue: String): String {
|
||||
return sharedPref.getString(key, defaultValue) ?: defaultValue
|
||||
fun delete(key: String) {
|
||||
sharedPref.edit().remove(key).apply()
|
||||
}
|
||||
}
|
||||
|
@ -4,11 +4,13 @@ import dagger.Module
|
||||
import dagger.android.ContributesAndroidInjector
|
||||
import io.github.wulkanowy.di.scopes.PerActivity
|
||||
import io.github.wulkanowy.services.job.SyncWorker
|
||||
import io.github.wulkanowy.services.widgets.TimetableWidgetService
|
||||
import io.github.wulkanowy.ui.modules.login.LoginActivity
|
||||
import io.github.wulkanowy.ui.modules.login.LoginModule
|
||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||
import io.github.wulkanowy.ui.modules.main.MainModule
|
||||
import io.github.wulkanowy.ui.modules.splash.SplashActivity
|
||||
import io.github.wulkanowy.ui.widgets.timetable.TimetableWidgetProvider
|
||||
|
||||
@Module
|
||||
internal abstract class BuilderModule {
|
||||
@ -25,6 +27,12 @@ internal abstract class BuilderModule {
|
||||
@ContributesAndroidInjector(modules = [MainModule::class])
|
||||
abstract fun bindMainActivity(): MainActivity
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract fun bindTimetableWidgetService(): TimetableWidgetService
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract fun bindTimetableWidgetProvider(): TimetableWidgetProvider
|
||||
|
||||
@ContributesAndroidInjector
|
||||
abstract fun bindSyncJob(): SyncWorker
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ import androidx.core.content.ContextCompat
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.db.entities.Grade
|
||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||
import io.github.wulkanowy.ui.modules.main.MainActivity.Companion.EXTRA_CARD_ID_KEY
|
||||
import io.github.wulkanowy.ui.modules.main.MainActivity.Companion.EXTRA_START_MENU_INDEX
|
||||
import timber.log.Timber
|
||||
|
||||
class GradeNotification(context: Context) : BaseNotification(context) {
|
||||
@ -41,7 +41,7 @@ class GradeNotification(context: Context) : BaseNotification(context) {
|
||||
.setColor(ContextCompat.getColor(context, R.color.colorPrimary))
|
||||
.setContentIntent(
|
||||
PendingIntent.getActivity(context, 0,
|
||||
MainActivity.getStartIntent(context).putExtra(EXTRA_CARD_ID_KEY, 0),
|
||||
MainActivity.getStartIntent(context).putExtra(EXTRA_START_MENU_INDEX, 0),
|
||||
FLAG_UPDATE_CURRENT
|
||||
)
|
||||
)
|
||||
|
@ -0,0 +1,27 @@
|
||||
package io.github.wulkanowy.services.widgets
|
||||
|
||||
import android.content.Intent
|
||||
import android.widget.RemoteViewsService
|
||||
import dagger.android.AndroidInjection
|
||||
import io.github.wulkanowy.data.db.SharedPrefHelper
|
||||
import io.github.wulkanowy.data.repositories.SessionRepository
|
||||
import io.github.wulkanowy.data.repositories.TimetableRepository
|
||||
import io.github.wulkanowy.ui.widgets.timetable.TimetableWidgetFactory
|
||||
import javax.inject.Inject
|
||||
|
||||
class TimetableWidgetService : RemoteViewsService() {
|
||||
|
||||
@Inject
|
||||
lateinit var timetableRepository: TimetableRepository
|
||||
|
||||
@Inject
|
||||
lateinit var sessionRepository: SessionRepository
|
||||
|
||||
@Inject
|
||||
lateinit var sharedPref: SharedPrefHelper
|
||||
|
||||
override fun onGetViewFactory(intent: Intent?): RemoteViewsFactory {
|
||||
AndroidInjection.inject(this)
|
||||
return TimetableWidgetFactory(timetableRepository, sessionRepository, sharedPref, applicationContext, intent)
|
||||
}
|
||||
}
|
@ -77,9 +77,7 @@ class GradePresenter @Inject constructor(
|
||||
}
|
||||
.subscribeOn(schedulers.backgroundThread)
|
||||
.observeOn(schedulers.mainThread)
|
||||
.subscribe({ _ ->
|
||||
view?.let { loadChild(it.currentPageIndex) }
|
||||
}) { errorHandler.proceed(it) })
|
||||
.subscribe({ view?.run { loadChild(currentPageIndex) } }) { errorHandler.proceed(it) })
|
||||
}
|
||||
|
||||
private fun loadChild(index: Int, forceRefresh: Boolean = false) {
|
||||
|
@ -32,7 +32,8 @@ class MainActivity : BaseActivity(), MainView {
|
||||
lateinit var navController: FragNavController
|
||||
|
||||
companion object {
|
||||
const val EXTRA_CARD_ID_KEY = "cardId"
|
||||
const val EXTRA_START_MENU_INDEX = "extraStartMenuIndex"
|
||||
|
||||
fun getStartIntent(context: Context) = Intent(context, MainActivity::class.java)
|
||||
}
|
||||
|
||||
@ -53,7 +54,7 @@ class MainActivity : BaseActivity(), MainView {
|
||||
setSupportActionBar(mainToolbar)
|
||||
messageContainer = mainFragmentContainer
|
||||
|
||||
presenter.onAttachView(this, intent.getIntExtra(EXTRA_CARD_ID_KEY, -1))
|
||||
presenter.onAttachView(this, intent.getIntExtra(EXTRA_START_MENU_INDEX, -1))
|
||||
navController.initialize(startMenuIndex, savedInstanceState)
|
||||
}
|
||||
|
||||
|
@ -12,12 +12,12 @@ class MainPresenter @Inject constructor(
|
||||
private val serviceHelper: ServiceHelper
|
||||
) : BasePresenter<MainView>(errorHandler) {
|
||||
|
||||
fun onAttachView(view: MainView, init: Int) {
|
||||
fun onAttachView(view: MainView, initMenuIndex: Int) {
|
||||
super.onAttachView(view)
|
||||
|
||||
view.run {
|
||||
cancelNotifications()
|
||||
startMenuIndex = if (init != -1) init else prefRepository.startMenuIndex
|
||||
startMenuIndex = if (initMenuIndex != -1) initMenuIndex else prefRepository.startMenuIndex
|
||||
initView()
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,93 @@
|
||||
package io.github.wulkanowy.ui.widgets.timetable
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Paint.ANTI_ALIAS_FLAG
|
||||
import android.graphics.Paint.STRIKE_THRU_TEXT_FLAG
|
||||
import android.view.View.GONE
|
||||
import android.view.View.VISIBLE
|
||||
import android.widget.AdapterView.INVALID_POSITION
|
||||
import android.widget.RemoteViews
|
||||
import android.widget.RemoteViewsService
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.db.SharedPrefHelper
|
||||
import io.github.wulkanowy.data.db.entities.Timetable
|
||||
import io.github.wulkanowy.data.repositories.SessionRepository
|
||||
import io.github.wulkanowy.data.repositories.TimetableRepository
|
||||
import io.github.wulkanowy.utils.toFormattedString
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import org.threeten.bp.LocalDate
|
||||
import timber.log.Timber
|
||||
|
||||
class TimetableWidgetFactory(
|
||||
private val timetableRepository: TimetableRepository,
|
||||
private val sessionRepository: SessionRepository,
|
||||
private val sharedPref: SharedPrefHelper,
|
||||
private val context: Context,
|
||||
private val intent: Intent?
|
||||
) : RemoteViewsService.RemoteViewsFactory {
|
||||
|
||||
private val disposable: CompositeDisposable = CompositeDisposable()
|
||||
|
||||
private var lessons = emptyList<Timetable>()
|
||||
|
||||
override fun getLoadingView() = null
|
||||
|
||||
override fun hasStableIds() = true
|
||||
|
||||
override fun getCount() = lessons.size
|
||||
|
||||
override fun getViewTypeCount() = 1
|
||||
|
||||
override fun getItemId(position: Int) = position.toLong()
|
||||
|
||||
override fun onCreate() {}
|
||||
|
||||
override fun onDataSetChanged() {
|
||||
intent?.action?.let { LocalDate.ofEpochDay(sharedPref.getLong(it, 0)) }
|
||||
?.let { date ->
|
||||
if (sessionRepository.isSessionSaved) {
|
||||
disposable.add(sessionRepository.getSemesters()
|
||||
.map { it.single { item -> item.current } }
|
||||
.flatMap { timetableRepository.getTimetable(it, date, date) }
|
||||
.map { item -> item.sortedBy { it.number } }
|
||||
.subscribe({ lessons = it })
|
||||
{ Timber.e(it, "An error has occurred while downloading data for the widget") })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getViewAt(position: Int): RemoteViews? {
|
||||
if (position == INVALID_POSITION) return null
|
||||
|
||||
return RemoteViews(context.packageName, R.layout.item_widget_timetable).apply {
|
||||
lessons[position].let {
|
||||
setTextViewText(R.id.timetableWidgetItemSubject, it.subject)
|
||||
setTextViewText(R.id.timetableWidgetItemNumber, it.number.toString())
|
||||
setTextViewText(R.id.timetableWidgetItemTime, it.start.toFormattedString("HH:mm") +
|
||||
" - ${it.end.toFormattedString("HH:mm")}")
|
||||
|
||||
if (it.room.isNotBlank()) {
|
||||
setTextViewText(R.id.timetableWidgetItemRoom, "${context.getString(R.string.timetable_room)} ${it.room}")
|
||||
} else setTextViewText(R.id.timetableWidgetItemRoom, "")
|
||||
|
||||
if (it.info.isNotBlank()) {
|
||||
setViewVisibility(R.id.timetableWidgetItemDescription, VISIBLE)
|
||||
setTextViewText(R.id.timetableWidgetItemDescription, it.info.capitalize())
|
||||
} else setViewVisibility(R.id.timetableWidgetItemDescription, GONE)
|
||||
|
||||
if (it.changes) {
|
||||
setInt(R.id.timetableWidgetItemSubject, "setPaintFlags",
|
||||
STRIKE_THRU_TEXT_FLAG or ANTI_ALIAS_FLAG)
|
||||
} else {
|
||||
setInt(R.id.timetableWidgetItemSubject, "setPaintFlags", ANTI_ALIAS_FLAG)
|
||||
}
|
||||
}
|
||||
setOnClickFillInIntent(R.id.timetableWidgetItemContainer, Intent())
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
disposable.clear()
|
||||
}
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
package io.github.wulkanowy.ui.widgets.timetable
|
||||
|
||||
import android.app.PendingIntent
|
||||
import android.app.PendingIntent.FLAG_UPDATE_CURRENT
|
||||
import android.appwidget.AppWidgetManager
|
||||
import android.appwidget.AppWidgetManager.ACTION_APPWIDGET_UPDATE
|
||||
import android.appwidget.AppWidgetManager.EXTRA_APPWIDGET_IDS
|
||||
import android.appwidget.AppWidgetProvider
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.widget.RemoteViews
|
||||
import dagger.android.AndroidInjection
|
||||
import io.github.wulkanowy.R
|
||||
import io.github.wulkanowy.data.db.SharedPrefHelper
|
||||
import io.github.wulkanowy.services.widgets.TimetableWidgetService
|
||||
import io.github.wulkanowy.ui.modules.main.MainActivity
|
||||
import io.github.wulkanowy.ui.modules.main.MainActivity.Companion.EXTRA_START_MENU_INDEX
|
||||
import io.github.wulkanowy.utils.nextOrSameSchoolDay
|
||||
import io.github.wulkanowy.utils.nextSchoolDay
|
||||
import io.github.wulkanowy.utils.previousSchoolDay
|
||||
import io.github.wulkanowy.utils.toFormattedString
|
||||
import io.github.wulkanowy.utils.weekDayName
|
||||
import org.threeten.bp.LocalDate
|
||||
import javax.inject.Inject
|
||||
|
||||
class TimetableWidgetProvider : AppWidgetProvider() {
|
||||
|
||||
@Inject
|
||||
lateinit var sharedPref: SharedPrefHelper
|
||||
|
||||
companion object {
|
||||
const val EXTRA_TOGGLED_WIDGET_ID = "extraToggledWidget"
|
||||
|
||||
const val EXTRA_BUTTON_TYPE = "extraButtonType"
|
||||
|
||||
const val BUTTON_NEXT = "buttonNext"
|
||||
|
||||
const val BUTTON_PREV = "buttonPrev"
|
||||
|
||||
const val BUTTON_RESET = "buttonReset"
|
||||
}
|
||||
|
||||
override fun onUpdate(context: Context?, appWidgetManager: AppWidgetManager?, appWidgetIds: IntArray?) {
|
||||
appWidgetIds?.forEach {
|
||||
val widgetKey = "timetable_widget_$it"
|
||||
checkSavedWidgetDate(widgetKey)
|
||||
|
||||
val savedDate = LocalDate.ofEpochDay(sharedPref.getLong(widgetKey, 0))
|
||||
context?.run {
|
||||
RemoteViews(packageName, R.layout.widget_timetable).apply {
|
||||
setTextViewText(R.id.timetableWidgetDay, savedDate.weekDayName.capitalize())
|
||||
setTextViewText(R.id.timetableWidgetDate, savedDate.toFormattedString())
|
||||
setEmptyView(R.id.timetableWidgetList, R.id.timetableWidgetEmpty)
|
||||
setRemoteAdapter(R.id.timetableWidgetList, Intent(context, TimetableWidgetService::class.java)
|
||||
.apply { action = widgetKey })
|
||||
setOnClickPendingIntent(R.id.timetableWidgetNext, createNavIntent(context, it, it, appWidgetIds, BUTTON_NEXT))
|
||||
setOnClickPendingIntent(R.id.timetableWidgetPrev, createNavIntent(context, -it, it, appWidgetIds, BUTTON_PREV))
|
||||
createNavIntent(context, Int.MAX_VALUE, it, appWidgetIds, BUTTON_RESET).let { intent ->
|
||||
setOnClickPendingIntent(R.id.timetableWidgetDate, intent)
|
||||
setOnClickPendingIntent(R.id.timetableWidgetDay, intent)
|
||||
}
|
||||
setPendingIntentTemplate(R.id.timetableWidgetList,
|
||||
PendingIntent.getActivity(context, 1, MainActivity.getStartIntent(context).apply {
|
||||
putExtra(EXTRA_START_MENU_INDEX, 3)
|
||||
}, FLAG_UPDATE_CURRENT))
|
||||
|
||||
}.also { view ->
|
||||
appWidgetManager?.apply {
|
||||
notifyAppWidgetViewDataChanged(it, R.id.timetableWidgetList)
|
||||
updateAppWidget(it, view)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onReceive(context: Context?, intent: Intent?) {
|
||||
AndroidInjection.inject(this, context)
|
||||
intent?.let {
|
||||
val widgetKey = "timetable_widget_${it.getIntExtra(EXTRA_TOGGLED_WIDGET_ID, 0)}"
|
||||
when (it.getStringExtra(EXTRA_BUTTON_TYPE)) {
|
||||
BUTTON_NEXT -> {
|
||||
LocalDate.ofEpochDay(sharedPref.getLong(widgetKey, 0)).nextSchoolDay
|
||||
.let { date -> sharedPref.putLong(widgetKey, date.toEpochDay(), true) }
|
||||
}
|
||||
BUTTON_PREV -> {
|
||||
LocalDate.ofEpochDay(sharedPref.getLong(widgetKey, 0)).previousSchoolDay
|
||||
.let { date -> sharedPref.putLong(widgetKey, date.toEpochDay(), true) }
|
||||
}
|
||||
BUTTON_RESET -> sharedPref.putLong(widgetKey, LocalDate.now().nextOrSameSchoolDay.toEpochDay(), true)
|
||||
}
|
||||
}
|
||||
super.onReceive(context, intent)
|
||||
}
|
||||
|
||||
override fun onDeleted(context: Context?, appWidgetIds: IntArray?) {
|
||||
appWidgetIds?.forEach {
|
||||
sharedPref.delete("timetable_widget_$it")
|
||||
}
|
||||
}
|
||||
|
||||
private fun createNavIntent(context: Context, code: Int, widgetId: Int, widgetIds: IntArray, buttonType: String): PendingIntent {
|
||||
return PendingIntent.getBroadcast(context, code,
|
||||
Intent(context, TimetableWidgetProvider::class.java).apply {
|
||||
action = ACTION_APPWIDGET_UPDATE
|
||||
putExtra(EXTRA_APPWIDGET_IDS, widgetIds)
|
||||
putExtra(EXTRA_BUTTON_TYPE, buttonType)
|
||||
putExtra(EXTRA_TOGGLED_WIDGET_ID, widgetId)
|
||||
}, FLAG_UPDATE_CURRENT)
|
||||
}
|
||||
|
||||
private fun checkSavedWidgetDate(widgetKey: String) {
|
||||
sharedPref.run {
|
||||
if (getLong(widgetKey, -1) == -1L) {
|
||||
putLong(widgetKey, LocalDate.now().nextOrSameSchoolDay.toEpochDay(), true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
BIN
app/src/main/res/drawable/ic_widget_chevron_24dp.png
Normal file
BIN
app/src/main/res/drawable/ic_widget_chevron_24dp.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 130 B |
BIN
app/src/main/res/drawable/img_timetable_widget_preview.png
Normal file
BIN
app/src/main/res/drawable/img_timetable_widget_preview.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
Binary file not shown.
Before Width: | Height: | Size: 11 KiB |
@ -1,67 +1,74 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/timetable_widget_item_container"
|
||||
android:id="@+id/timetableWidgetItemContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/ic_all_divider"
|
||||
android:minHeight="45dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/timetable_widget_item_time"
|
||||
android:id="@+id/timetableWidgetItemNumber"
|
||||
android:layout_width="55dp"
|
||||
android:layout_height="45dp"
|
||||
android:gravity="center"
|
||||
android:text="0"
|
||||
android:textSize="25sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/timetableWidgetItemTime"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_toEndOf="@id/timetableWidgetItemNumber"
|
||||
android:layout_toRightOf="@id/timetableWidgetItemNumber"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@color/second_text_color"
|
||||
android:textSize="14sp" />
|
||||
android:textSize="13sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/timetable_widget_item_subject"
|
||||
android:id="@+id/timetableWidgetItemSubject"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="25dp"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginRight="25dp"
|
||||
android:layout_marginStart="15dp"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginTop="5dp"
|
||||
android:layout_toEndOf="@id/timetable_widget_item_time"
|
||||
android:layout_toRightOf="@id/timetable_widget_item_time"
|
||||
android:layout_marginEnd="25dp"
|
||||
android:layout_marginRight="25dp"
|
||||
android:layout_toEndOf="@id/timetableWidgetItemTime"
|
||||
android:layout_toRightOf="@id/timetableWidgetItemTime"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@color/second_text_color"
|
||||
android:textSize="14sp" />
|
||||
android:textSize="13sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/timetable_widget_item_description"
|
||||
android:id="@+id/timetableWidgetItemDescription"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/timetable_widget_item_subject"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:layout_marginEnd="25dp"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginRight="25dp"
|
||||
android:layout_below="@id/timetableWidgetItemSubject"
|
||||
android:layout_marginStart="15dp"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginTop="3dp"
|
||||
android:layout_toEndOf="@id/timetable_widget_item_time"
|
||||
android:layout_toRightOf="@id/timetable_widget_item_time"
|
||||
android:layout_marginEnd="25dp"
|
||||
android:layout_marginRight="25dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:layout_toEndOf="@id/timetableWidgetItemTime"
|
||||
android:layout_toRightOf="@id/timetableWidgetItemTime"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@color/colorPrimaryDark"
|
||||
android:textSize="12sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/timetable_widget_item_room"
|
||||
android:id="@+id/timetableWidgetItemRoom"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/timetable_widget_item_time"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_below="@id/timetableWidgetItemTime"
|
||||
android:layout_marginTop="3dp"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:layout_toEndOf="@id/timetableWidgetItemNumber"
|
||||
android:layout_toRightOf="@id/timetableWidgetItemNumber"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@color/second_text_color"
|
||||
android:textSize="12sp" />
|
||||
|
||||
|
||||
</RelativeLayout>
|
||||
|
@ -2,70 +2,81 @@
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:foreground="@android:color/white">
|
||||
android:background="@android:color/white">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/timetable_widget_bar_height"
|
||||
android:background="@color/colorPrimary">
|
||||
|
||||
<Button
|
||||
android:id="@+id/timetable_widget_toggle"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
<ImageButton
|
||||
android:id="@+id/timetableWidgetPrev"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginStart="5dp"
|
||||
android:layout_marginLeft="5dp"
|
||||
android:backgroundTint="@color/colorPrimaryDark"
|
||||
android:text="@string/widget_timetable_today"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="12sp" />
|
||||
android:contentDescription="@string/all_prev"
|
||||
android:src="@drawable/ic_widget_chevron_24dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/timetable_widget_date"
|
||||
android:id="@+id/timetableWidgetDay"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_marginBottom="5dp"
|
||||
android:layout_marginEnd="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:layout_toEndOf="@id/timetable_widget_title"
|
||||
android:layout_toRightOf="@id/timetable_widget_title"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center"
|
||||
android:layout_alignTop="@+id/timetableWidgetPrev"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_toStartOf="@id/timetableWidgetNext"
|
||||
android:layout_toLeftOf="@id/timetableWidgetNext"
|
||||
android:layout_toEndOf="@id/timetableWidgetPrev"
|
||||
android:layout_toRightOf="@id/timetableWidgetPrev"
|
||||
android:gravity="center_horizontal"
|
||||
android:maxLines="1"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="13sp" />
|
||||
android:textSize="15sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/timetable_widget_title"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/timetable_widget_bar_height"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_toLeftOf="@id/timetable_widget_toggle"
|
||||
android:layout_toStartOf="@id/timetable_widget_toggle"
|
||||
android:ellipsize="end"
|
||||
android:gravity="center_vertical"
|
||||
android:id="@+id/timetableWidgetDate"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/timetableWidgetDay"
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_marginTop="3dp"
|
||||
android:layout_toStartOf="@id/timetableWidgetNext"
|
||||
android:layout_toLeftOf="@id/timetableWidgetNext"
|
||||
android:layout_toEndOf="@id/timetableWidgetPrev"
|
||||
android:layout_toRightOf="@id/timetableWidgetPrev"
|
||||
android:gravity="center_horizontal"
|
||||
android:maxLines="1"
|
||||
android:text="@string/timetable_title"
|
||||
android:text="@string/app_name"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="20sp" />
|
||||
android:textSize="14sp" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/timetableWidgetNext"
|
||||
android:layout_width="70dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:layout_marginRight="5dp"
|
||||
android:backgroundTint="@color/colorPrimaryDark"
|
||||
android:contentDescription="@string/all_next"
|
||||
android:rotation="180"
|
||||
android:src="@drawable/ic_widget_chevron_24dp" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<ListView
|
||||
android:id="@+id/timetable_widget_list"
|
||||
android:id="@+id/timetableWidgetList"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="@dimen/timetable_widget_bar_height" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/timetable_widget_empty"
|
||||
android:id="@+id/timetableWidgetEmpty"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
|
@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:initialLayout="@layout/widget_timetable"
|
||||
android:minHeight="100dp"
|
||||
android:minWidth="150dp"
|
||||
android:minHeight="100dp"
|
||||
android:previewImage="@drawable/img_timetable_widget_preview"
|
||||
android:resizeMode="horizontal|vertical"
|
||||
android:updatePeriodMillis="3600000"
|
||||
android:updatePeriodMillis="7200000"
|
||||
android:widgetCategory="home_screen" />
|
||||
|
Loading…
Reference in New Issue
Block a user