diff --git a/doubletapplayerview/README.md b/doubletapplayerview/README.md new file mode 100644 index 000000000..76cbdb555 --- /dev/null +++ b/doubletapplayerview/README.md @@ -0,0 +1,182 @@ +# DoubleTapPlayerView + +A simple library to include double tap behavior to ExoPlayer's PlayerView. +Created to handle fast forward/rewind behavior like YouTube. + +![teamwork-flip](github/preview_gif.gif) + +# Sample app + +If you would like to test the YouTube overlay, then you can either download the demo app, +which can be found under Assets of the release or build it yourself from code. +It provides all main modifications available. + +The sample videos own by *Blender Foundation* and a full list can be found [here][videolist]. + +# Download + +The Gradle dependency is available via [jitpack.io][jitpack]. +To be able to load this library, you have to add the repository to your project's gradle file: + +```gradle +allprojects { + repositories { + ... + maven { url 'https://jitpack.io' } + } +} +``` + +Then, in your app's directory, you can include it the same way like other libraries: + +```gradle +android { + ... + // If you face problems during building you should try including the below lines if you + // haven't already + + // compileOptions { + // sourceCompatibility JavaVersion.VERSION_1_8 + // targetCompatibility JavaVersion.VERSION_1_8 + // } +} + +dependencies { + implementation 'com.github.vkay94:DoubleTapPlayerView:1.0.4' +} +``` + +The minimum API level supported by this library is API 16 as ExoPlayer does, but I can't +verify versions below API level 21 (Lollipop) myself. So feedback is welcomed. + +# Getting started + +In order to start using the YouTube overlay, the easiest way is to include it directly +into your XML layout, e.g. on top of `DoubleTapPlayerView` or inside ExoPlayer's controller: + +```xml + + + + + + +``` + +Then, inside your `Activity` or `Fragment`, you can specify which preparations should be done +before and after the animation, but at least, you have got to toggle the visibility of the +overlay and reference the (Simple)ExoPlayer to it: + +```kotlin +youtube_overlay + .performListener(object : YouTubeOverlay.PerformListener { + override fun onAnimationStart() { + // Do UI changes when circle scaling animation starts (e.g. hide controller views) + youtube_overlay.visibility = View.VISIBLE + } + + override fun onAnimationEnd() { + // Do UI changes when circle scaling animation starts (e.g. show controller views) + youtube_overlay.visibility = View.GONE + } + }) + // Uncomment this line if you haven't set yt_playerView in XML + // .playerView(playerView) + +// Uncomment this line if you haven't set dtpv_controller in XML +// playerView.controller(youtube_overlay) + +// Call this method whenever the player is released and recreated +youtube_overlay.player(simpleExoPlayer) +``` + +This way, you have more control about the appearance, for example you could apply a fading +animation to it. For a full initialization you can refer to the demo application's MainActivity +and layout files. + +--- + +# API documentation + +The following sections provide detailed documentation for the components of the library. + +## DoubleTapPlayerView + +`DoubleTapPlayerView` is the core of this library. It recognizes specific gestures +which provides more control for the double tapping gesture. +An overview about the added methods can be found in the [PlayerDoubleTapListener][PlayerDoubleTapListener] +interface. + +You can adjust how long the double tap mode remains after the last action, +the default value is 650 milliseconds. + +## YouTubeOverlay + +`YouTubeOverlay` is the reason for this library. It provides nearly the +same experience like the fast forward/rewind feature which is used by YouTube's +Android app. It is highly modifiable. + +### XML attributes + +If you add the view to your XML layout you can set some custom attributes +to customize the view's look and behavior. +Every attributes value can also be get and set programmatically. + +| Attribute name | Description | Type | +| ------------- | ------------| ------| +| `yt_seekSeconds` | Fast forward/rewind seconds skip per tap. The text *xx seconds* will be changed where xx is `value`. | `int` | +| `yt_animationDuration` | Speed of the circle scaling / time in millis to expand completely. When this time has passed, YouTubeOverlay's `PerformListener.onAnimationEnd()` will be called. | `int` | +| `yt_arcSize` | Arc of the background circle. The higher the value the more roundish the shape becomes. This attribute should be set dynamically depending on screen size and orientation. | `dimen` | +| `yt_tapCircleColor` | Color of the scaling circle after tap. | `color` | +| `yt_backgroundCircleColor` | Color of the background shape. | `color` | +| `yt_iconAnimationDuration` | Time in millis to run through an full fade cycle. | `int` | +| `yt_icon` | One of the three forward icons. Will be multiplied by three and mirrored for rewind. | `drawable` | +| `yt_textAppearance` | Text appearance for the *xx seconds* text. | `style` | + +I'd recommend the sample app to try out the different values for them. + +### YouTubeOverlay.PerformListener + +This interface listens to the *lifecycle* of the overlay. + +```kotlin +// Obligatory: Called when the overlay is not visible and the first valid double tap event occurred. +// Visibility of the overlay should be set to VISIBLE within this interface method. +fun onAnimationStart() + +// Obligatory: Called when the circle animation is finished. +// Visibility of the overlay should be set to GONE or INVISIBLE within this interface method. +fun onAnimationEnd() + +// Optional: Determines whether the player should forward (true), rewind (false) or ignore (null) taps. +fun shouldForward(player: Player, playerView: DoubleTapPlayerView, posX: Float): Boolean? +``` + +### SeekListener + +This interface reacts to the events during rewinding/forwarding. + +```kotlin +// Called when the start of the video is reached +fun onVideoStartReached() + +// Called when the end of the video is reached +fun onVideoEndReached() +``` + +[videolist]: https://gist.github.com/jsturgis/3b19447b304616f18657 +[jitpack]: https://jitpack.io/#vkay94/DoubleTapPlayerView +[PlayerDoubleTapListener]: https://github.com/vkay94/DoubleTapPlayerView/blob/master/doubletapplayerview/src/main/java/com/github/vkay94/dtpv/PlayerDoubleTapListener.java diff --git a/filepicker-lib/README.md b/filepicker-lib/README.md new file mode 100644 index 000000000..902e2d49d --- /dev/null +++ b/filepicker-lib/README.md @@ -0,0 +1,122 @@ +# Material File Picker by Arte al Programar + +Material file picker library for Android by Arte al Programar + +![](ss/main.png) + +## What's new + +- Require Android Jelly Bean 4.1.x (API 16+) +- Material You (Dynamics Color) Support +- Night Mode Support +- New Icon Designs + +## Add your project + +Using Jcenter + +``` +build.gradle (Project) + +allprojects { + repositories { + maven { url 'https://jitpack.io' } + } +} + + +build.gradle (Module: app) + +dependencies { + ... + // Java + implementation 'androidx.activity:activity:1.4.0' + implementation 'androidx.fragment:fragment:1.4.1' + + // Kotlin + implementation 'androidx.activity:activity-ktx:1.4.0' + implementation 'androidx.fragment:fragment-ktx:1.4.1' + implementation 'com.github.arteaprogramar:Android-MaterialFilePicker:3.0.1' +} + + +``` + +## Using (IMPORTANT) + +- For Android 11 and above, you must request "MANAGE_EXTERNAL_STORAGE" permission in your + application, "Material File Picker" requires that permission to read and show user files. + +- Open your class and add the following code + +``` +... +kotlin + +/** + * This library require "Activity Result" API + **/ + +private val startForResultFiles = registerForActivityResult( + ActivityResultContracts.StartActivityForResult() +) { result: ActivityResult -> + onActivityResult(result.resultCode, result.data) +} + +... + +// External Storage Path +val externalStorage = FileUtils.getFile(applicationContext, null) + +MaterialFilePicker() + // Pass a source of context. Can be: + // .withActivity(Activity activity) + // .withFragment(Fragment fragment) + // .withSupportFragment(androidx.fragment.app.Fragment fragment) + .withActivity(this) + // With cross icon on the right side of toolbar for closing picker straight away + .withCloseMenu(true) + // Entry point path (user will start from it) + //.withPath(alarmsFolder.absolutePath) + // Root path (user won't be able to come higher than it) + .withRootPath(externalStorage.absolutePath) + // Showing hidden files + .withHiddenFiles(true) + // Want to choose only jpg images + .withFilter(Pattern.compile(".*\\.(jpg|jpeg)$")) + // Don't apply filter to directories names + .withFilterDirectories(false) + .withTitle("Sample title") + // Require "Activity Result" API + .withActivityResultApi(startForResultFiles) + .start() +... + + +/** + * For Android API 29+, You need + * + * And some extra settings. + * You can check the demo of the application + **/ + + +``` + +Override on activity result: + +``` +kotlin + +private fun onActivityResult(resultCode: Int, data: Intent?) { + if (resultCode == Activity.RESULT_OK) { + val path: String? = data?.getStringExtra(FilePickerActivity.RESULT_FILE_PATH) + + if (path != null) { + Log.d("Path: ", path) + Toast.makeText(this, "Picked file: $path", Toast.LENGTH_LONG).show() + } + } +} + +``` \ No newline at end of file diff --git a/slidableactivity/README.md b/slidableactivity/README.md new file mode 100644 index 000000000..639893a48 --- /dev/null +++ b/slidableactivity/README.md @@ -0,0 +1,196 @@ +# Deprecated +This library is no longer supported as the modern convention of building Android apps switches from multi-Activity to single-Activity. If you are looking for similar behavior look into supporting Android's new [predictive back handling](https://developer.android.com/guide/navigation/custom-back/predictive-back-gesture) + +Slidr +================ +[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.r0adkll/slidableactivity/badge.svg?style=flat)](https://maven-badges.herokuapp.com/maven-central/com.r0adkll/slidableactivity) [![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-Slidr-brightgreen.svg?style=flat)](https://android-arsenal.com/details/1/1364) +[![Build Status](https://travis-ci.org/r0adkll/Slidr.svg?branch=master)](https://travis-ci.org/r0adkll/Slidr) + +Easily add slide-to-dismiss functionality to your Activity by calling `Slidr.attach(this)` in your `onCreate(..)` method. + +![Slidr Example](images/slidr_gif.gif "Gif Example") + +## Usage + +An example usage: + +```java +public class ExampleActivity extends { + + @Override + public void onCreate(Bundle savedInstanceState){ + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_example); + int primary = getResources().getColor(R.color.primaryDark); + int secondary = getResources().getColor(R.color.secondaryDark); + Slidr.attach(this, primary, secondary); + } + +} +``` + +or + +```java +public class ExampleActivity extends { + + @Override + public void onCreate(Bundle savedInstanceState){ + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_example); + Slidr.attach(this); + } + +} +``` + +## Fragments +The activity must extend FragmentActivity. +Set the background to the main container of the activity in the xml `background="@android:color/transparent"`. +Add the following code to the Fragment: + +```java +// This interface is needed to see if the fragment +// is resuming after creation (Slidr to be attached) or +// simply from the background (app was paused before). +SlidrInterface slidrInterface; + +@Override +public void onResume() { + super.onResume(); + if(slidrInterface == null) + slidrInterface = Slidr.replace(getView().findViewById(R.id.content_container), new SlidrConfig.Builder().position(SlidrPosition.LEFT).build()); +} +``` +In the xml of the fragment's view, the root view must be a FrameLayout with the same background set to the activity before. Add a child viewgroup to it with the id content_container. E.g.: + +```xml + + + + + ...other stuff + + + +``` +Remember: you have to add new Fragments with: + +```java +getSupportFragmentManager().beginTransaction() + .add(R.id.fragment_container, YourFragmentClass.newInstance()) + .commit(); +``` + +where fragment_container is the id of a FrameLayout inside the activity's xml. + + +## Configuring + +```java +SlidrConfig config = new SlidrConfig.Builder() + .primaryColor(getResources().getColor(R.color.primary) + .secondaryColor(getResources().getColor(R.color.secondary) + .position(SlidrPosition.LEFT|RIGHT|TOP|BOTTOM|VERTICAL|HORIZONTAL) + .sensitivity(1f) + .scrimColor(Color.BLACK) + .scrimStartAlpha(0.8f) + .scrimEndAlpha(0f) + .velocityThreshold(2400) + .distanceThreshold(0.25f) + .edge(true|false) + .edgeSize(0.18f) // The % of the screen that counts as the edge, default 18% + .listener(new SlidrListener(){...}) + .build(); + +Slidr.attach(this, config); + +``` + +--- + +`Slidr.attach(...)` will return a `SlidrInterface` which gives you access to two methods: + +```java +SlidrInterface.lock(); +SlidrInterface.unlock(); +``` + +These methods lock or unlock the slidable touch interface. + +The theme that you use for your sliding activity must have these attributes set: + +```xml +true +@android:color/transparent +``` + +Then in the layout of your activity you must give it a background like this; + +```xml + + + ... +``` + +## Including in your project + +Include this line in your gradle build file: + +```groovy +implementation 'com.r0adkll:slidableactivity:2.1.0' +``` + + + + +## Author + +- Drew Heavner, **[r0adkll](http://r0adkll.com)** + +## License + + Copyright (c) 2014 Drew Heavner + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + either express or implied. See the License for the specific + language governing permissions and limitations under the License.