Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 616833c9 authored by Ricki Hirner's avatar Ricki Hirner
Browse files

Remove deprecated kotlin-android-extensions in favor of view bindings

parent 520f96f0
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -9,7 +9,6 @@
apply plugin: 'com.android.application'
apply plugin: 'com.mikepenz.aboutlibraries.plugin'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
apply plugin: 'org.jetbrains.dokka'

@@ -48,7 +47,10 @@ android {
        jvmTarget = "1.8"
    }

    buildFeatures.dataBinding = true
    buildFeatures {
        viewBinding = true
        dataBinding = true
    }

    flavorDimensions "distribution"
    productFlavors {
+53 −27
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
package at.bitfire.davdroid.ui

import android.app.Application
import android.content.Context
import android.os.Build
import android.os.Bundle
import android.text.Spanned
@@ -17,7 +18,6 @@ import android.util.DisplayMetrics
import android.view.*
import androidx.annotation.UiThread
import androidx.appcompat.app.AppCompatActivity
import androidx.cardview.widget.CardView
import androidx.core.text.HtmlCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
@@ -32,12 +32,12 @@ import androidx.recyclerview.widget.RecyclerView
import at.bitfire.davdroid.App
import at.bitfire.davdroid.BuildConfig
import at.bitfire.davdroid.R
import at.bitfire.davdroid.databinding.AboutBinding
import at.bitfire.davdroid.databinding.AboutLanguagesBinding
import at.bitfire.davdroid.databinding.AboutTranslationBinding
import at.bitfire.davdroid.databinding.ActivityAboutBinding
import com.mikepenz.aboutlibraries.Libs
import com.mikepenz.aboutlibraries.LibsBuilder
import kotlinx.android.synthetic.main.about.*
import kotlinx.android.synthetic.main.about_languages.*
import kotlinx.android.synthetic.main.about_translation.view.*
import kotlinx.android.synthetic.main.activity_about.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.apache.commons.io.IOUtils
@@ -57,15 +57,20 @@ class AboutActivity: AppCompatActivity() {

    }

    private lateinit var binding: ActivityAboutBinding


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_about)

        setSupportActionBar(toolbar)
        binding = ActivityAboutBinding.inflate(layoutInflater)
        setContentView(binding.root)

        setSupportActionBar(binding.toolbar)
        supportActionBar?.setDisplayHomeAsUpEnabled(true)

        viewpager.adapter = TabsAdapter(supportFragmentManager)
        tabs.setupWithViewPager(viewpager, false)
        binding.viewpager.adapter = TabsAdapter(supportFragmentManager)
        binding.tabs.setupWithViewPager(binding.viewpager, false)
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
@@ -115,67 +120,88 @@ class AboutActivity: AppCompatActivity() {

    class AppFragment: Fragment() {

        private var _binding: AboutBinding? = null
        private val binding get() = _binding!!
        val model by viewModels<TextFileModel>()

        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) =
                inflater.inflate(R.layout.about, container, false)!!
        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
            _binding = AboutBinding.inflate(inflater, container, false)
            return binding.root
        }

        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            app_name.setText(R.string.app_name)
            app_version.text = getString(R.string.about_version, BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE)
            build_time.text = getString(R.string.about_build_date, SimpleDateFormat.getDateInstance().format(BuildConfig.buildTime))
            binding.appName.setText(R.string.app_name)
            binding.appVersion.text = getString(R.string.about_version, BuildConfig.VERSION_NAME, BuildConfig.VERSION_CODE)
            binding.buildTime.text = getString(R.string.about_build_date, SimpleDateFormat.getDateInstance().format(BuildConfig.buildTime))

            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
                icon.setImageDrawable(resources.getDrawableForDensity(R.mipmap.ic_launcher, DisplayMetrics.DENSITY_XXXHIGH, null))
                binding.icon.setImageDrawable(resources.getDrawableForDensity(R.mipmap.ic_launcher, DisplayMetrics.DENSITY_XXXHIGH, null))

            pixels.text = HtmlCompat.fromHtml(pixelsHtml, HtmlCompat.FROM_HTML_MODE_LEGACY)
            binding.pixels.text = HtmlCompat.fromHtml(pixelsHtml, HtmlCompat.FROM_HTML_MODE_LEGACY)

            if (true /* open-source version */) {
                warranty.setText(R.string.about_license_info_no_warranty)
                binding.warranty.setText(R.string.about_license_info_no_warranty)

                model.initialize("gplv3.html", true)
                model.htmlText.observe(viewLifecycleOwner, { spanned ->
                    license_text.text = spanned
                    binding.licenseText.text = spanned
                })
            }
        }

        override fun onDestroyView() {
            super.onDestroyView()
            _binding = null
        }

    }

    class LanguagesFragment: Fragment() {

        private var _binding: AboutLanguagesBinding? = null
        private val binding get() = _binding!!
        val model by viewModels<TranslationsModel>()

        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?) =
                inflater.inflate(R.layout.about_languages, container, false)!!
        override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
            _binding = AboutLanguagesBinding.inflate(inflater, container, false)
            return binding.root
        }

        override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
            model.initialize("translators.json", false)
            model.translations.observe(viewLifecycleOwner, { translations ->
                translators.adapter = TranslationsAdapter(translations)
                binding.translators.adapter = TranslationsAdapter(translations)
            })

            translators.layoutManager = LinearLayoutManager(requireActivity())
            binding.translators.layoutManager = LinearLayoutManager(requireActivity())
        }

        override fun onDestroyView() {
            super.onDestroyView()
            _binding = null
        }


        class TranslationsAdapter(
                val translations: List<TranslationsModel.Translation>
        ): RecyclerView.Adapter<TranslationsAdapter.ViewHolder>() {

            class ViewHolder(val cardView: CardView): RecyclerView.ViewHolder(cardView)
            private lateinit var binding: AboutTranslationBinding

            class ViewHolder(val context: Context, val binding: AboutTranslationBinding): RecyclerView.ViewHolder(binding.root)

            override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
                val tv = LayoutInflater.from(parent.context).inflate(R.layout.about_translation, parent, false) as CardView
                return ViewHolder(tv)
                binding = AboutTranslationBinding.inflate(LayoutInflater.from(parent.context), parent, false)
                return ViewHolder(parent.context, binding)
            }

            override fun onBindViewHolder(holder: ViewHolder, position: Int) {
                val translation = translations[position]
                holder.cardView.apply {
                holder.binding.apply {
                    language.text = translation.language
                    val profiles = translation.translators.map { "<a href='https://www.transifex.com/user/profile/$it'>$it</a>" }
                    translators.text = HtmlCompat.fromHtml(
                            context.getString(R.string.about_translations_thanks, profiles.joinToString(", ")),
                            holder.context.getString(R.string.about_translations_thanks, profiles.joinToString(", ")),
                            HtmlCompat.FROM_HTML_MODE_COMPACT)
                    translators.movementMethod = LinkMovementMethod.getInstance()
                }
+27 −18
Original line number Diff line number Diff line
@@ -33,39 +33,43 @@ import androidx.recyclerview.widget.RecyclerView
import at.bitfire.davdroid.DavUtils
import at.bitfire.davdroid.DavUtils.SyncStatus
import at.bitfire.davdroid.R
import at.bitfire.davdroid.databinding.AccountListBinding
import at.bitfire.davdroid.databinding.AccountListItemBinding
import at.bitfire.davdroid.ui.account.AccountActivity
import kotlinx.android.synthetic.main.account_list.*
import kotlinx.android.synthetic.main.account_list_item.view.*
import java.text.Collator

class AccountListFragment: Fragment() {

    private var _binding: AccountListBinding? = null
    private val binding get() = _binding!!
    val model by viewModels<Model>()

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        setHasOptionsMenu(true)
        return inflater.inflate(R.layout.account_list, container, false)

        _binding = AccountListBinding.inflate(inflater, container, false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        model.networkAvailable.observe(viewLifecycleOwner, { networkAvailable ->
            no_network_info.visibility = if (networkAvailable) View.GONE else View.VISIBLE
            binding.noNetworkInfo.visibility = if (networkAvailable) View.GONE else View.VISIBLE
        })

        val accountAdapter = AccountAdapter(requireActivity())
        list.apply {
        binding.list.apply {
            layoutManager = LinearLayoutManager(requireActivity())
            adapter = accountAdapter
        }
        model.accounts.observe(viewLifecycleOwner, { accounts ->
            if (accounts.isEmpty()) {
                list.visibility = View.GONE
                empty.visibility = View.VISIBLE
                binding.list.visibility = View.GONE
                binding.empty.visibility = View.VISIBLE
            } else {
                list.visibility = View.VISIBLE
                empty.visibility = View.GONE
                binding.list.visibility = View.VISIBLE
                binding.empty.visibility = View.GONE
            }
            accountAdapter.submitList(accounts)
            requireActivity().invalidateOptionsMenu()
@@ -82,6 +86,11 @@ class AccountListFragment: Fragment() {
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }


    class AccountAdapter(
            val activity: Activity
@@ -93,18 +102,18 @@ class AccountListFragment: Fragment() {
                        oldItem == newItem
            }
    ) {
        class ViewHolder(val v: View): RecyclerView.ViewHolder(v)

        class ViewHolder(val binding: AccountListItemBinding): RecyclerView.ViewHolder(binding.root)

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
            val v = LayoutInflater.from(parent.context).inflate(R.layout.account_list_item, parent, false)
            return ViewHolder(v)
            val binding = AccountListItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
            return ViewHolder(binding)
        }

        override fun onBindViewHolder(holder: ViewHolder, position: Int) {
            val v = holder.v
            val accountInfo = currentList[position]

            v.setOnClickListener {
            holder.binding.root.setOnClickListener {
                val intent = Intent(activity, AccountActivity::class.java)
                intent.putExtra(AccountActivity.EXTRA_ACCOUNT, accountInfo.account)
                activity.startActivity(intent)
@@ -112,23 +121,23 @@ class AccountListFragment: Fragment() {

            when (accountInfo.status) {
                SyncStatus.ACTIVE -> {
                    v.progress.apply {
                    holder.binding.progress.apply {
                        alpha = 1.0f
                        isIndeterminate = true
                        visibility = View.VISIBLE
                    }
                }
                SyncStatus.PENDING -> {
                    v.progress.apply {
                    holder.binding.progress.apply {
                        alpha = 0.4f
                        isIndeterminate = false
                        progress = 100
                        visibility = View.VISIBLE
                    }
                }
                else -> v.progress.visibility = View.INVISIBLE
                else -> holder.binding.progress.visibility = View.INVISIBLE
            }
            v.account_name.text = accountInfo.account.name
            holder.binding.accountName.text = accountInfo.account.name
        }
    }

+17 −15
Original line number Diff line number Diff line
@@ -23,13 +23,11 @@ import androidx.core.content.getSystemService
import androidx.core.view.GravityCompat
import at.bitfire.davdroid.DavUtils
import at.bitfire.davdroid.R
import at.bitfire.davdroid.databinding.ActivityAccountsBinding
import at.bitfire.davdroid.ui.intro.IntroActivity
import at.bitfire.davdroid.ui.setup.LoginActivity
import com.google.android.material.navigation.NavigationView
import com.google.android.material.snackbar.Snackbar
import kotlinx.android.synthetic.main.accounts_content.*
import kotlinx.android.synthetic.main.activity_accounts.*
import kotlinx.android.synthetic.main.activity_accounts.view.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
@@ -43,6 +41,8 @@ class AccountsActivity: AppCompatActivity(), NavigationView.OnNavigationItemSele
        const val REQUEST_INTRO = 0
    }

    private lateinit var binding: ActivityAccountsBinding

    private var syncStatusSnackbar: Snackbar? = null
    private var syncStatusObserver: Any? = null

@@ -60,21 +60,23 @@ class AccountsActivity: AppCompatActivity(), NavigationView.OnNavigationItemSele
            }
        }

        setContentView(R.layout.activity_accounts)
        setSupportActionBar(toolbar)
        binding = ActivityAccountsBinding.inflate(layoutInflater)
        setContentView(binding.root)

        fab.setOnClickListener {
        val content = binding.content
        setSupportActionBar(binding.content.toolbar)
        content.fab.setOnClickListener {
            startActivity(Intent(this, LoginActivity::class.java))
        }
        fab.show()
        content.fab.show()

        val toggle = ActionBarDrawerToggle(
                this, drawer_layout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)
        drawer_layout.addDrawerListener(toggle)
                this, binding.drawerLayout, binding.content.toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close)
        binding.drawerLayout.addDrawerListener(toggle)
        toggle.syncState()

        nav_view.setNavigationItemSelectedListener(this)
        nav_view.itemIconTintList = null
        binding.navView.setNavigationItemSelectedListener(this)
        binding.navView.itemIconTintList = null

        // handle "Sync all" intent from launcher shortcut
        if (savedInstanceState == null && intent.action == Intent.ACTION_SYNC)
@@ -84,7 +86,7 @@ class AccountsActivity: AppCompatActivity(), NavigationView.OnNavigationItemSele
    override fun onResume() {
        super.onResume()

        accountsDrawerHandler.initMenu(this, drawer_layout.nav_view.menu)
        accountsDrawerHandler.initMenu(this, binding.navView.menu)

        onStatusChanged(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS)
        syncStatusObserver = ContentResolver.addStatusChangeListener(ContentResolver.SYNC_OBSERVER_TYPE_SETTINGS, this)
@@ -125,15 +127,15 @@ class AccountsActivity: AppCompatActivity(), NavigationView.OnNavigationItemSele
    }

    override fun onBackPressed() {
        if (drawer_layout.isDrawerOpen(GravityCompat.START))
            drawer_layout.closeDrawer(GravityCompat.START)
        if (binding.drawerLayout.isDrawerOpen(GravityCompat.START))
            binding.drawerLayout.closeDrawer(GravityCompat.START)
        else
            super.onBackPressed()
    }

    override fun onNavigationItemSelected(item: MenuItem): Boolean {
        val processed = accountsDrawerHandler.onNavigationItemSelected(this, item)
        drawer_layout.closeDrawer(GravityCompat.START)
        binding.drawerLayout.closeDrawer(GravityCompat.START)
        return processed
    }

+9 −4
Original line number Diff line number Diff line
@@ -15,7 +15,6 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.observe
import at.bitfire.davdroid.PackageChangedReceiver
import at.bitfire.davdroid.R
import at.bitfire.davdroid.databinding.ActivityTasksBinding
@@ -23,15 +22,16 @@ import at.bitfire.davdroid.resource.TaskUtils
import at.bitfire.davdroid.settings.SettingsManager
import at.bitfire.ical4android.TaskProvider.ProviderName
import com.google.android.material.snackbar.Snackbar
import kotlinx.android.synthetic.main.activity_tasks.*

class TasksFragment: Fragment() {

    private var _binding: ActivityTasksBinding? = null
    private val binding get() = _binding!!
    val model by viewModels<Model>()


    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
        val binding = ActivityTasksBinding.inflate(inflater, container, false)
        _binding = ActivityTasksBinding.inflate(inflater, container, false)
        binding.lifecycleOwner = viewLifecycleOwner
        binding.model = model

@@ -63,13 +63,18 @@ class TasksFragment: Fragment() {
        return binding.root
    }

    override fun onDestroyView() {
        super.onDestroyView()
        _binding = null
    }

    private fun installApp(packageName: String) {
        val uri = Uri.parse("market://details?id=$packageName")
        val intent = Intent(Intent.ACTION_VIEW, uri)
        if (intent.resolveActivity(requireActivity().packageManager) != null)
            startActivity(intent)
        else
            Snackbar.make(frame, R.string.intro_tasks_no_app_store, Snackbar.LENGTH_LONG).show()
            Snackbar.make(binding.frame, R.string.intro_tasks_no_app_store, Snackbar.LENGTH_LONG).show()
    }


Loading