Git Product home page Git Product logo

android-extensions's Introduction

Android Extensions

Navigation Tests

Please note, this is not an official Google or Android repository and has no affiliation with the aforementioned parties.

It is merely a fairly long lived, albeit well maintained side project. Caveat emptor.

This repository is a collection of modules to help bootstrap an Android Application. There are 10 modules:

Name Description
1 App A sample app demoing the modules in the repository.
2 Core A few added utilities to the core Android KTX libraries. Includes extension methods on objects to side step ContextCompat, DrawableCompat, and a fluent SpannableString API
3 Navigation Interfaces and implementations of Fragment based Navigators, including single and multiple stacks. The APIs allow for hooking into the raw FragmentTransactions that run allow you to customize it to your heart's content. Suspending APIs are also available to preform navigation actions sequentially without having to deal with the asynchrosity of the FragmentManager.
4 View A module containing UI building blocks, like animators and helper methods for views. Built mostly around the SpringAnimation from the Jetpack DynamicAnimation library. In the example to the right, it is responsible for animating the margin, and padding of the container views, and the hiding and showing of bouncing FABs.
5 RecyclerView Utility classes for the RecyclerView ViewGroup like drag and drop, swipe gestures, endless scrolling, a composable adapter, diffing, tables and much more.
6 ViewPager2 Utility classes for the ViewPager2 ViewGroup particularly diff util for dispatching updates
7 Material Utility classes around Google's Material Design components including an expandable floating action button.
8 Communications Utility classes for Near Service Discovery (NSD) and Bluetooth Low Energy (BLE) communication.
9 Saved State Delegated implementation of Android Jetpack's Saved State Registry for Components that also have a lifecycle.
10 ConstraintLayout (Unmaintained, MotionLayout is here) Utility classes for the ConstraintLayout ViewGroup.
11 Test (Unmaintained) Testing utilities built mostly around Espresso.

build.gradle lines

The built artifacts are hosted on Jcenter (pending the looming shutdown) and Maven Central:

    allprojects {
        repositories {
            // Pre jcenter shutdown
            Jcenter()
            // Now or post Jcenter shutdown
            mavenCentral()
        }
    }

    implementation 'com.tunjid.androidx:module:x.x.x'

Refer to the table above for the latest version information.

If you so desire, you can fork the repo and host the artifacts your self using github packages. Refer to publishing information below for more details.

Projects that use This library include:

  1. DigiLux Fingerprint gestures app
  2. BluetoothRcSwitch IOT Github project

Core

Read more about the core module, classes and components here.

A medium post with some of it's offerings can be read here and here .

View

Read more about the view module, classes and components here. A medium post with some of it's offerings can be read here.

RecyclerView

Read more about the RecyclerView module, classes and components here. A medium post with some of it's offerings can be read here.

ConstraintLayout

Read more about the ConstraintLayout module, classes and components here. A medium post with some of it's offerings can be read here.

Material

Read more about the Material module, classes and components here. A medium post with some of it's offerings can be read here.

Communications

Read more about the communications module, classes and components here. A project using it can be seen here.

Test

Warning, here be dragons, I haven't updated this in a bit; move fast, break things and all that. I mean, yeah I could test more, but thank Heavens for QA, amirite? ๐Ÿ™ƒ You can read more about the testing module and classes here.

Image attribution App icon made by Freepik from www.flaticon.com is licensed by [CC 3.0 BY](http://creativecommons.org/licenses/by/3.0/ "Creative Commons BY 3.0"

Publishing

Publishing is done with the maven-publish plugin.

To publish, run:

./gradlew incrementalPublish

This will publish the latest version of every module, and will not override existing versions. The version of the module is determined by the version.properties file. To bump a module version, bump it in version.properties.

Publishing configuration is done by using a publishInfo.json file in the project root directory. A sample publishInfo.json looks like:

{
  "signArtifacts": true,
  "signingPassword": "mySigningPassword",
  "signingKey": "-----BEGIN PGP PRIVATE KEY BLOCK-----ADD YOUR GPG KEY HERE-----END PGP PRIVATE KEY BLOCK-----\n",
  "versionSuffix": "myVersionSuffix",
  "repositories": [
    {
      "name": "TunjiGithub",
      "publishUrl": "https://maven.pkg.github.com/tunjid/Android-Extensions",
      "downloadUrl": "https://maven.pkg.github.com/tunjid/Android-Extensions",
      "credentials": {
        "username": "tunjid",
        "password": "githubAuthToken"
      }
    },
    {
      "name": "TunjiMavenCentral",
      "publishUrl": "https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/",
      "downloadUrl": "https://repo1.maven.org/maven2",
      "credentials": {
        "username": "myMavenCentralUsername",
        "password": "myMavenCentralPassword"
      }
    }
  ]
}

signArtifacts, signingPassword, signingKey and versionSuffix properties are not necessary and may be omitted; in fact, I personally only need to sign my artifacts when uploading to maven central.

Note that the repository name NEEDS to be camel cased as it's used when finding the gradle task to publish the artifact.

You do however need to specify at least 1 maven repository to publish to if you intend to publish artifacts.

If you intend to host your own version of the artifacts on github packages after forking the repository, you will need to add a secret to your github action pipeline. The secret key is PUBLISH_INFO_JSON, and the value is the publishInfo.json described above, substituting the values of publishUrl and downloadUrl to match the url of your github fork and the credentials matching your username and github auth token.

android-extensions's People

Contributors

dependabot[bot] avatar lolaodelola avatar petergelsomino avatar tunjid avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

android-extensions's Issues

How to use MaterialFadeThrough Transition as StackTransactionModifier?

Hi,

very nice library!

Currently I am asking myself how to implement MaterialFadeThrough-Transition during a stack-change?

I was able to implement a Cross-Fade Transition by using stackTransactionModifier of MultiStackNavigator like this
this.stackTransactionModifier = { setCustomAnimations( R.anim.fade_in, R.anim.fade_out, R.anim.fade_in, R.anim.fade_out ) }

But how to do this by using a MaterialFadeThrough Transition?

Example of Instagram-Like Navigation

Hi,

would it be possible to add the Instagram-like navigation example from https://proandroiddev.com/simplifying-the-fragmentmanager-api-multiple-fragment-backstacks-on-android-9b64ddb0d654 also seen in the following gif

https://miro.medium.com/max/648/1*Rj7f7D3XfwUuXFlBnBSQ1A.gif

to the sample app?

I'm asking because I need exactly that but I don't really understand how to transfer the knowledge from the sample app to my app, where I pretty much need exactly what one can see in the gif.

In particular, I'm wondering how the fragments in the main activity are created since the root function in the sample app appears to create a new fragment each time it is called. Also, I was wondering how the inner fragments should be added in such a way that their state is preserved.

Please let me know if you need more information since the explanation I gave here is rather brief.

Minimal steps needed to implement speed dial

I'm not sure how to use the speed dial components without all the complex UI driver stuff. These are the steps I followed:

  1. I added a dependency on com.tunjid.androidx:material:1.0.0-rc06 to my app's build.gradle
  2. I copied the SpeedDialClickListener class into my project (aside: it would be nice if this was provided by a lib), along with the missing resources it used (R.drawable.ic_unfold_less_24dp and R.drawable.ic_unfold_more_24dp)
  3. I added a MaterialButton to my fragment layout
  4. I added the following code to my fragment:
    private var _fabExtended = true
    private lateinit var _fabExtensionAnimator: FabExtensionAnimator
    private lateinit var _fabClickListener: SpeedDialClickListener
    private var _fabTransitionOptions: SpringAnimation.() -> Unit = {}

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

        val speedDialItems = createSpeedDialItems()

        _fabExtensionAnimator = FabExtensionAnimator(expandable_fab).apply {
            speedDialItems[1].run { updateGlyphs(first, second) }
        }

        _fabClickListener = SpeedDialClickListener(
            tint = view.context.themeColorAt(R.attr.colorAccent),
            items = speedDialItems,
            runGuard = this@MainFragment::fabExtensionGuard,
            dismissListener = {
                when (it) {
                    null -> Unit
                    0 -> {
                        _fabExtended = true
                        _fabExtensionAnimator.configureSpring(_fabTransitionOptions)
                    }
                    else -> speedDialItems[it].run {
                        _fabExtensionAnimator.updateGlyphs(first, second)
                    }
                }
            }
        )

        expandable_fab.setOnClickListener {
            _fabExtensionAnimator.isExtended = !_fabExtensionAnimator.isExtended
        }
    }

    private fun fabExtensionGuard(view: View): Boolean {
        if (!_fabExtended) return true
        _fabExtended = false
        _fabExtensionAnimator.configureSpring(_fabTransitionOptions)
        _fabTransitionOptions = { speedDialRecall(view) }
        return false
    }

    private fun SpringAnimation.speedDialRecall(view: View) = withOneShotEndListener {
        if (_fabExtended) return@withOneShotEndListener
        _fabClickListener.invoke(view)
    }

    private fun createSpeedDialItems() = requireActivity().run {
        listOf(
            "Item 1" to getDrawable(R.drawable.ic_folder)!!,
            "Item 2" to getDrawable(R.drawable.ic_folder_special)!!
        )
    }

When I run the app, the button shows the text and icon for the first speed dial item, but I expected it to show the unfold icon. Clicking the button expands the button and shows the label next to the icon but doesn't show the speed dial items.

Needless to say, I don't really understand what all this code does. I get really confused when I look into the GlobalUiDriver class, so I'd rather not have to add all of that.

Can't perform this action after onSaveInstanceState

java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
        at androidx.fragment.app.FragmentManager.checkStateLoss(FragmentManager.java:1689)
        at androidx.fragment.app.FragmentManager.enqueueAction(FragmentManager.java:1729)
        at androidx.fragment.app.BackStackRecord.commitInternal(BackStackRecord.java:321)
        at androidx.fragment.app.BackStackRecord.commit(BackStackRecord.java:286)
        at com.emaar.shopndrop.navigation.MultiStackNavigator.showInternal(MultiStackNavigator.kt:320)
        at com.emaar.shopndrop.navigation.MultiStackNavigator.show(MultiStackNavigator.kt:119)
        at com.emaar.shopndrop.activities.MainActivity$fetchRequestDetail$1.onNext(MainActivity.kt:193)
        at com.emaar.shopndrop.activities.MainActivity$fetchRequestDetail$1.onNext(MainActivity.kt:178)
        at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.drainNormal(ObservableObserveOn.java:201)
        at io.reactivex.internal.operators.observable.ObservableObserveOn$ObserveOnObserver.run(ObservableObserveOn.java:255)
        at io.reactivex.android.schedulers.HandlerScheduler$ScheduledRunnable.run(HandlerScheduler.java:124)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7356)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)

@tunjid I'm getting this error. What I'm trying is after launching MainActivity hitting the web API and launching fragment.

BackStackType Unlimited/Restricted in version 1.2.1 not working correctly

Hi @tunjid,

I just checked out version 1.2.1. Thanks for the changes.

I discovered that something is not working correctly with BackstackType Unlimited or Restricted. Its working fine with uniqueEntries. I ONLY changed the type to Unlimited/Restricted.

Back press navigation within a tab with several fragments seems to work fine as well as switching then to the previous tab, but if the next previous tab just has only a root fragment I have to press twice the back button.

It seems that it only occurs if I just navigate back between tabs with only root fragment added to it.

Wrong order of selected tabs during back press?

Hi @tunjid,

its me again! :)

If I start you example project and click myself through the tabs in the following order

Nav, Lists, Comms, Misc, Comms, Lists, Nav (From left to right and back to left)

I would expect that while I am pressing the back button I would go through

Lists, Comms, Misc, Comms, Lists, Nav and finally app is moved to background

but instead the order is

Lists, Comms, Misc and finally app is moved to background

is that the right behavior?

StackNavigator shared element transition between activities

Hi @tunjid,

actually I discovered an issue while implementing shared element transitions between activities by using StackNavigator.
The issue is that the back transition of the shared element transition is not working because every fragment is added to the back stack. Every means that also the initial one is added to the back stack.

The issues lies within
StackNavigator.push(fragment:Fragment, tag:String)

to be more precise

fragmentManager.commit {
            transactionModifier?.invoke(this, fragment)
            replace(containerId, fragmentToShow, tag)
            addToBackStack(tag.toEntry)
        }

Is there a way to circumvent "addToBackStack(tag.toEntry)?

If I do not use StackNavigator and simple use a transaction where I do not add the initial fragment to the back stack then the back transition of the shared element transition is working fine.

Do you need an example project?

Regards
wMan

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.