Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • videostreaming/futopayclientlibraries
  • alex/futopayclientlibraries
2 results
Show changes
Commits on Source (4)
Showing
with 123 additions and 553 deletions
# Default ignored files
/shelf/
/workspace.xml
PolycentricCore
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AndroidTestResultsUserPreferences">
<option name="androidTestResultsTableState">
<map>
<entry key="-2030737957">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_3a_API_33_x86_64" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="-1888365331">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="R5CNC07TZCY" value="120" />
<entry key="Tests" value="360" />
<entry key="samsung&#10; SM-G998B" value="120" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="-1766545009">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="R5CNC07TZCY" value="120" />
<entry key="Tests" value="360" />
<entry key="samsung&#10; SM-G998B" value="120" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="-1603504896">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="R5CNC07TZCY" value="120" />
<entry key="Tests" value="360" />
<entry key="samsung&#10; SM-G998B" value="120" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="-1533817792">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_3a_API_33_x86_64" value="120" />
<entry key="R5CNC07TZCY" value="120" />
<entry key="Tests" value="360" />
<entry key="samsung&#10; SM-G998B" value="120" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="-1348472475">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="29211JEGR13699" value="120" />
<entry key="Duration" value="90" />
<entry key="Google&#10; Pixel 6a" value="120" />
<entry key="R5CNC07TZCY" value="120" />
<entry key="Tests" value="360" />
<entry key="samsung&#10; SM-G998B" value="120" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="-1191746456">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="R5CNC07TZCY" value="120" />
<entry key="Tests" value="360" />
<entry key="samsung&#10; SM-G998B" value="120" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="-1089424001">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="R5CNC07TZCY" value="120" />
<entry key="Tests" value="360" />
<entry key="samsung&#10; SM-G998B" value="120" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="-1030942155">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="29211JEGR13699" value="120" />
<entry key="Duration" value="90" />
<entry key="Google&#10; Pixel 6a" value="120" />
<entry key="Pixel_3a_API_33_x86_64" value="120" />
<entry key="Pixel_C_API_33" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="-1013244967">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="R5CNC07TZCY" value="120" />
<entry key="Tests" value="360" />
<entry key="samsung&#10; SM-G998B" value="120" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="-998275601">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="29211JEGR13699" value="120" />
<entry key="Duration" value="90" />
<entry key="Google&#10; Pixel 6a" value="120" />
<entry key="Pixel_3a_API_33_x86_64" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="-693989101">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="R5CNC07TZCY" value="120" />
<entry key="Tests" value="360" />
<entry key="samsung&#10; SM-G998B" value="120" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="-483192549">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_3a_API_33_x86_64" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="-396783379">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="29211JEGR13699" value="120" />
<entry key="Duration" value="90" />
<entry key="Google&#10; Pixel 6a" value="120" />
<entry key="Pixel_3a_API_33_x86_64" value="120" />
<entry key="Pixel_C_API_33" value="120" />
<entry key="R5CNC07TZCY" value="120" />
<entry key="Tests" value="360" />
<entry key="samsung&#10; SM-G998B" value="120" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="-285941453">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_3a_API_33_x86_64" value="120" />
<entry key="R5CNC07TZCY" value="120" />
<entry key="Tests" value="360" />
<entry key="samsung&#10; SM-G998B" value="120" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="-43042216">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_3a_API_33_x86_64" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="143109477">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="29211JEGR13699" value="120" />
<entry key="Duration" value="90" />
<entry key="Google&#10; Pixel 6a" value="120" />
<entry key="R5CNC07TZCY" value="120" />
<entry key="Tests" value="360" />
<entry key="samsung&#10; SM-G998B" value="120" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="217836404">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_3a_API_33_x86_64" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="309039273">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="R5CNC07TZCY" value="120" />
<entry key="Tests" value="360" />
<entry key="samsung&#10; SM-G998B" value="120" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="568179418">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="R5CNC07TZCY" value="120" />
<entry key="Tests" value="360" />
<entry key="samsung&#10; SM-G998B" value="120" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="728115857">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_3a_API_33_x86_64" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="762617096">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="29211JEGR13699" value="120" />
<entry key="Duration" value="90" />
<entry key="Google&#10; Pixel 6a" value="120" />
<entry key="R5CNC07TZCY" value="120" />
<entry key="Tests" value="360" />
<entry key="samsung&#10; SM-G998B" value="120" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="1154603043">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="29211JEGR13699" value="120" />
<entry key="Duration" value="90" />
<entry key="Google&#10; Pixel 6a" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="1367930197">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_3a_API_33_x86_64" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="1392532197">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_3a_API_33_x86_64" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="1445499490">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Pixel_3a_API_33_x86_64" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="1489134328">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="29211JEGR13699" value="120" />
<entry key="Duration" value="90" />
<entry key="Google&#10; Pixel 6a" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="1814633309">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="R5CNC07TZCY" value="120" />
<entry key="Tests" value="360" />
<entry key="samsung&#10; SM-G998B" value="120" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="1823866028">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="R5CNC07TZCY" value="120" />
<entry key="Tests" value="360" />
<entry key="samsung&#10; SM-G998B" value="120" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="1824280393">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="R5CNC07TZCY" value="120" />
<entry key="Tests" value="360" />
<entry key="samsung&#10; SM-G998B" value="120" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="1956518097">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="29211JEGR13699" value="120" />
<entry key="Duration" value="90" />
<entry key="Google&#10; Pixel 6a" value="120" />
<entry key="Pixel_3a_API_33_x86_64" value="120" />
<entry key="R5CNC07TZCY" value="120" />
<entry key="Tests" value="360" />
<entry key="samsung&#10; SM-G998B" value="120" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
<entry key="2076253436">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="29211JEGR13699" value="120" />
<entry key="Duration" value="90" />
<entry key="Google&#10; Pixel 6a" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
</map>
</option>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="17" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="deploymentTargetDropDown">
<targetSelectedWithDropDown>
<Target>
<type value="QUICK_BOOT_TARGET" />
<deviceKey>
<Key>
<type value="VIRTUAL_DEVICE_PATH" />
<value value="$USER_HOME$/.android/avd/Pixel_C_API_33.avd" />
</Key>
</deviceKey>
</Target>
</targetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2023-08-03T14:42:06.113626110Z" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="Embedded JDK" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinJpsPluginSettings">
<option name="version" value="1.7.20" />
</component>
</project>
\ No newline at end of file
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
plugins { plugins {
id 'com.android.library' id 'com.android.library'
id 'org.jetbrains.kotlin.android' id 'org.jetbrains.kotlin.android'
id 'org.jetbrains.kotlin.plugin.serialization' version '1.6.10' id 'org.jetbrains.kotlin.plugin.serialization' version '1.8.20'
} }
android { android {
...@@ -9,8 +9,8 @@ android { ...@@ -9,8 +9,8 @@ android {
compileSdk 33 compileSdk 33
defaultConfig { defaultConfig {
minSdk 26 minSdk 24
targetSdk 32 targetSdk 33
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
...@@ -31,10 +31,10 @@ android { ...@@ -31,10 +31,10 @@ android {
} }
dependencies { dependencies {
implementation 'androidx.core:core-ktx:1.9.0' implementation 'androidx.core:core-ktx:1.10.1'
implementation 'androidx.appcompat:appcompat:1.4.1' implementation 'androidx.appcompat:appcompat:1.6.1'
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4"
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.4.1" implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1'
implementation 'androidx.recyclerview:recyclerview:1.3.0' implementation 'androidx.recyclerview:recyclerview:1.3.0'
implementation 'com.caverock:androidsvg-aar:1.4' implementation 'com.caverock:androidsvg-aar:1.4'
implementation 'com.google.code.gson:gson:2.10.1' implementation 'com.google.code.gson:gson:2.10.1'
......
package com.futo.futopay package com.futo.futopay
import android.content.Context
import android.util.Log import android.util.Log
import android.view.ViewGroup import android.view.ViewGroup
import androidx.activity.ComponentActivity
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.LifecycleCoroutineScope
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.stripe.android.PaymentConfiguration import com.stripe.android.PaymentConfiguration
import com.stripe.android.paymentsheet.PaymentSheet import com.stripe.android.paymentsheet.PaymentSheet
...@@ -11,50 +14,53 @@ import kotlinx.coroutines.CoroutineScope ...@@ -11,50 +14,53 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.io.BufferedReader
import java.io.InputStreamReader
import java.net.HttpURLConnection
import java.net.URL import java.net.URL
interface PaymentStatusListener {
fun onSuccess();
fun onCancel();
fun onFailure(error: Throwable);
}
class PaymentManager { class PaymentManager {
private val _fragment: Fragment; private val _fragment: Fragment;
private val _overlayContainer: ViewGroup; private val _overlayContainer: ViewGroup;
private val _sheet: PaymentSheet; private val _sheet: PaymentSheet;
private val _paymentState: PaymentState; private val _paymentState: PaymentState;
private val _listener: PaymentStatusListener;
constructor(paymentState: PaymentState, fragment: Fragment, overlayContainer: ViewGroup, onCompleted: (success: Boolean, exception: Throwable?)->Unit) { constructor(paymentState: PaymentState, fragment: Fragment, overlayContainer: ViewGroup, listener: PaymentStatusListener) {
_fragment = fragment; _fragment = fragment;
_paymentState = paymentState; _paymentState = paymentState;
_overlayContainer = overlayContainer; _overlayContainer = overlayContainer;
_listener = listener;
_sheet = PaymentSheet(_fragment) { paymentSheetResult -> _sheet = PaymentSheet(_fragment) { paymentSheetResult ->
when(paymentSheetResult) { when(paymentSheetResult) {
is PaymentSheetResult.Canceled -> { is PaymentSheetResult.Canceled -> {
_listener.onCancel();
} }
is PaymentSheetResult.Failed -> { is PaymentSheetResult.Failed -> {
onCompleted(false, paymentSheetResult.error) _listener.onFailure(paymentSheetResult.error);
} }
is PaymentSheetResult.Completed -> { is PaymentSheetResult.Completed -> {
onCompleted(true, null); _listener.onSuccess();
} }
} }
}; };
} }
fun startPayment(paymentState: PaymentState, scope: CoroutineScope, productId: String) { fun startPayment(paymentState: PaymentState, scope: CoroutineScope, productId: String) {
scope.launch(Dispatchers.IO){ scope.launch(Dispatchers.IO){
try{ try{
val availableCurrencies = _paymentState.getAvailableCurrencies(productId); val availableCurrencies = _paymentState.getAvailableCurrencies(productId);
val country = paymentState.getPaymentCountryFromIP()?.let { c -> PaymentConfigurations.COUNTRIES.find { it.id.equals(c, ignoreCase = true) } }; val country = paymentState.getPaymentCountryFromIP()?.let { c -> PaymentConfigurations.COUNTRIES.find { it.id.equals(c, ignoreCase = true) } };
withContext(Dispatchers.Main) { withContext(Dispatchers.Main) {
SlideUpPayment.startPayment(paymentState, _overlayContainer, productId, country, availableCurrencies) { method, request -> SlideUpPayment.startPayment(paymentState, _overlayContainer, productId, country, availableCurrencies, { method, request ->
when(method) { when(method) {
"stripe" -> startPaymentStripe(productId, request.currency, request.mail, request.country, request.zipcode); "stripe" -> startPaymentStripe(productId, request.currency, request.mail, request.country, request.zipcode);
} }
}; }, { _listener.onCancel() });
} }
} }
catch(ex: Throwable) { catch(ex: Throwable) {
......
...@@ -54,7 +54,7 @@ class SlideUpPayment : RelativeLayout { ...@@ -54,7 +54,7 @@ class SlideUpPayment : RelativeLayout {
private var _isVisible = false; private var _isVisible = false;
var onOK: (() -> Unit)? = null; var onOK: (() -> Unit)? = null;
var onCancel: (() -> Unit)? = null; var onCancel: (() -> Unit)? = SlideUpPayment._onCancel;
constructor(paymentState: PaymentState, context: Context, parent: ViewGroup, titleText: String, okText: String?, vararg items: View): super(context){ constructor(paymentState: PaymentState, context: Context, parent: ViewGroup, titleText: String, okText: String?, vararg items: View): super(context){
init(paymentState, okText); init(paymentState, okText);
...@@ -86,7 +86,9 @@ class SlideUpPayment : RelativeLayout { ...@@ -86,7 +86,9 @@ class SlideUpPayment : RelativeLayout {
private var _currentSlideUpPayment: SlideUpPayment? = null; private var _currentSlideUpPayment: SlideUpPayment? = null;
private val _animationDuration = 300L; private val _animationDuration = 300L;
fun startPayment(paymentState: PaymentState, overlayContainer: ViewGroup, productId: String, country: PaymentConfigurations.CountryDescriptor?, currencies: List<String>? = null, onSelected: (String, PaymentManager.PaymentRequest)->Unit) { private var _onCancel: (() -> Unit)? = null;
fun startPayment(paymentState: PaymentState, overlayContainer: ViewGroup, productId: String, country: PaymentConfigurations.CountryDescriptor?, currencies: List<String>? = null, onSelected: (String, PaymentManager.PaymentRequest)->Unit, onCancel: () -> Unit) {
_productId = productId; _productId = productId;
_paymentMethod = null; _paymentMethod = null;
_country = country; _country = country;
...@@ -94,6 +96,7 @@ class SlideUpPayment : RelativeLayout { ...@@ -94,6 +96,7 @@ class SlideUpPayment : RelativeLayout {
_currency = country?.let { c -> PaymentConfigurations.CURRENCIES.find { it.id == c.defaultCurrencyId && (_currencies?.contains(it.id) ?: true) } }; _currency = country?.let { c -> PaymentConfigurations.CURRENCIES.find { it.id == c.defaultCurrencyId && (_currencies?.contains(it.id) ?: true) } };
_postalCode = null; _postalCode = null;
_onSelected = onSelected; _onSelected = onSelected;
_onCancel = onCancel;
_currentSlideUpPayment = null; _currentSlideUpPayment = null;
requestNext(paymentState, overlayContainer); requestNext(paymentState, overlayContainer);
......
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1500"
android:propertyName="rotation"
android:valueFrom="0"
android:valueTo="360"
android:repeatMode="restart"
android:repeatCount="infinite"
android:interpolator="@android:anim/linear_interpolator" />
\ No newline at end of file
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:propertyName="rotation"
android:valueFrom="0"
android:valueTo="360"
android:repeatMode="restart"
android:repeatCount="infinite"
android:interpolator="@android:anim/linear_interpolator" />
\ No newline at end of file
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2500"
android:propertyName="rotation"
android:valueFrom="0"
android:valueTo="-360"
android:repeatMode="restart"
android:repeatCount="infinite"
android:interpolator="@android:anim/linear_interpolator" />
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#303030" />
<corners android:radius="4dp" />
<padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" />
</shape>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#000000" />
<corners android:radius="6dp" />
<padding android:left="0dp" android:top="0dp" android:right="0dp" android:bottom="0dp" />
</shape>
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="16dp"
android:viewportWidth="16"
android:viewportHeight="16">
<path
android:pathData="M16,1.611L14.389,0L8,6.389L1.611,0L0,1.611L6.389,8L0,14.389L1.611,16L8,9.611L14.389,16L16,14.389L9.611,8L16,1.611Z"
android:fillColor="#ffffff"/>
</vector>
\ No newline at end of file
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="125dp"
android:height="125dp"
android:viewportWidth="280"
android:viewportHeight="280">
<group android:translateX="26"
android:translateY="20">
<group
android:name="rotationGroup1"
android:pivotX="113.0"
android:pivotY="121.0"
android:rotation="0.0">
<path
android:pathData="M57.31,63.67C25.81,94.29 24.91,144.64 55.38,176.37C85.84,208.1 136.19,209.24 168.06,179.01L158.36,168.92C132.07,193.79 90.59,192.83 65.47,166.67C40.36,140.52 41.09,99.03 67.01,73.77L57.31,63.67Z"
android:fillColor="#2D63ED"
android:fillType="evenOdd"/>
</group>
<group
android:name="rotationGroup2"
android:pivotX="113.0"
android:pivotY="121.0"
android:rotation="0.0">
<path
android:pathData="M15.01,136.36C23.41,190.35 73.83,227.51 127.96,219.45C182.09,211.38 219.49,161.13 211.77,107.04L197.93,109.1C204.5,155.55 172.37,198.68 125.9,205.6C79.42,212.53 36.11,180.64 28.86,134.29L15.01,136.36Z"
android:fillColor="#0044C8"
android:fillType="evenOdd"/>
</group>
<group
android:name="rotationGroup3"
android:pivotX="113.0"
android:pivotY="121.0"
android:rotation="0.0">
<path
android:pathData="M96.53,239.8C161.63,249.14 222.15,204.18 231.92,139.04C241.69,73.9 197.01,13.17 132.04,3L129.96,16.85C187.29,25.86 226.69,79.47 218.07,136.96C209.45,194.45 156.06,234.15 98.61,225.95L96.53,239.8Z"
android:fillColor="#0022A6"
android:fillType="evenOdd"/>
</group>
</group>
</vector>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_loader" >
<target
android:name="rotationGroup1"
android:animation="@animator/rotation_1500_clockwise" />
<target
android:name="rotationGroup2"
android:animation="@animator/rotation_2500_counter_clockwise" />
<target
android:name="rotationGroup3"
android:animation="@animator/rotation_2000_clockwise" />
</animated-vector>
\ No newline at end of file