├── .gitignore ├── CHANGELOG.md ├── README.md ├── alfonz-adapter ├── README.md ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── org │ │ └── alfonz │ │ └── adapter │ │ ├── AdapterView.java │ │ ├── BaseDataBoundPagerAdapter.java │ │ ├── BaseDataBoundRecyclerAdapter.java │ │ ├── BaseDataBoundRecyclerViewHolder.java │ │ ├── DataBoundListAdapter.java │ │ ├── MultiDataBoundPagerAdapter.java │ │ ├── MultiDataBoundRecyclerAdapter.java │ │ ├── MultiMapDataBoundRecyclerAdapter.java │ │ ├── SimpleDataBoundPagerAdapter.java │ │ ├── SimpleDataBoundRecyclerAdapter.java │ │ ├── SimpleMapDataBoundRecyclerAdapter.java │ │ ├── callback │ │ ├── OnPagerListChangedCallback.java │ │ ├── OnRecyclerListChangedCallback.java │ │ ├── OnRecyclerMapChangedCallback.java │ │ ├── RecyclerListChangedCallbackHolder.java │ │ └── RecyclerMapChangedCallbackHolder.java │ │ ├── utility │ │ └── BindingUtility.java │ │ └── widget │ │ ├── GridDividerItemDecoration.java │ │ └── GridSpacingItemDecoration.java │ └── res │ └── layout │ └── binding_variables.xml ├── alfonz-arch ├── README.md ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── org │ │ └── alfonz │ │ └── arch │ │ ├── AlfonzActivity.java │ │ ├── AlfonzBindingActivity.java │ │ ├── AlfonzBindingFragment.java │ │ ├── AlfonzFragment.java │ │ ├── AlfonzView.java │ │ ├── AlfonzViewModel.java │ │ ├── bundle │ │ ├── AlfonzBundleViewModel.java │ │ └── AlfonzBundleViewModelFactory.java │ │ ├── event │ │ ├── Event.java │ │ ├── EventObserver.java │ │ ├── LiveBus.java │ │ └── LiveEvent.java │ │ ├── utility │ │ └── BindingUtility.java │ │ └── widget │ │ └── ToolbarIndicator.java │ └── res │ ├── drawable │ └── ic_close.xml │ ├── layout │ └── binding_variables.xml │ └── values │ └── ids.xml ├── alfonz-graphics ├── README.md ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── org │ └── alfonz │ └── graphics │ ├── bitmap │ ├── BitmapBlur.java │ ├── BitmapReflection.java │ └── BitmapScaler.java │ └── drawable │ ├── CircularDrawable.java │ ├── PlaceholderDrawable.java │ └── RoundedDrawable.java ├── alfonz-media ├── README.md ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── org │ └── alfonz │ └── media │ ├── ImagePicker.java │ └── SoundManager.java ├── alfonz-rest ├── README.md ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── org │ └── alfonz │ └── rest │ ├── HttpException.java │ ├── HttpLogger.java │ ├── ResponseHandler.java │ ├── call │ ├── BaseCallManager.java │ ├── CallManager.java │ └── Callback.java │ ├── http │ └── GzipRequestInterceptor.java │ └── rx │ └── RestRxManager.java ├── alfonz-rx ├── README.md ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── org │ └── alfonz │ └── rx │ ├── AlfonzDisposableCompletableObserver.java │ ├── AlfonzDisposableMaybeObserver.java │ ├── AlfonzDisposableObserver.java │ ├── AlfonzDisposableSingleObserver.java │ ├── RxBus.java │ ├── RxManager.java │ └── utility │ └── SchedulersUtility.java ├── alfonz-utility ├── README.md ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── org │ └── alfonz │ └── utility │ ├── ContentUtility.java │ ├── DateConvertor.java │ ├── DeviceUuidFactory.java │ ├── DimensionUtility.java │ ├── DownloadUtility.java │ ├── HashUtility.java │ ├── IntentUtility.java │ ├── KeyboardUtility.java │ ├── Logcat.java │ ├── NetworkUtility.java │ ├── PermissionManager.java │ ├── ResourcesUtility.java │ ├── ServiceUtility.java │ ├── StorageUtility.java │ ├── StringConvertor.java │ ├── ValidationUtility.java │ ├── VersionUtility.java │ └── ZipUtility.java ├── alfonz-view ├── README.md ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── org │ │ └── alfonz │ │ └── view │ │ ├── AspectRatioImageView.java │ │ ├── EllipsizingTextView.java │ │ ├── MaxWidthLinearLayout.java │ │ ├── ObservableScrollView.java │ │ ├── RotatableImageView.java │ │ ├── SelectorFrameLayout.java │ │ ├── SelectorLinearLayout.java │ │ ├── SelectorRelativeLayout.java │ │ └── StatefulLayout.java │ └── res │ └── values │ └── attrs.xml ├── bintray.gradle ├── build.gradle ├── extras └── graphics │ ├── alfonz.gif │ └── avatar.gif ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── install.gradle ├── samples ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── assets │ └── sound.mp3 │ ├── java │ └── org │ │ └── alfonz │ │ └── samples │ │ ├── SamplesActivity.java │ │ ├── SamplesApplication.java │ │ ├── SamplesConfig.java │ │ ├── alfonzadapter │ │ ├── AdapterSampleActivity.java │ │ ├── AdapterSampleDiffViewModel.java │ │ ├── AdapterSampleGridSimpleFragment.java │ │ ├── AdapterSampleListDiffFragment.java │ │ ├── AdapterSampleListMultiFragment.java │ │ ├── AdapterSampleListSimpleFragment.java │ │ ├── AdapterSamplePagerMultiFragment.java │ │ ├── AdapterSamplePagerSimpleFragment.java │ │ ├── AdapterSampleView.java │ │ ├── AdapterSampleViewModel.java │ │ ├── MessageListDiffAdapter.java │ │ ├── MessageListMultiAdapter.java │ │ ├── MessageListSimpleAdapter.java │ │ ├── MessagePagerMultiAdapter.java │ │ └── MessagePagerSimpleAdapter.java │ │ ├── alfonzarch │ │ ├── ArchSampleActivity.java │ │ ├── ArchSampleFragment.java │ │ ├── ArchSampleView.java │ │ ├── ArchSampleViewModel.java │ │ ├── ArchSampleViewModelActivity.java │ │ ├── ArchSampleViewModelFactory.java │ │ ├── BaseActivity.java │ │ ├── BaseFragment.java │ │ ├── BaseViewModel.java │ │ └── event │ │ │ ├── SnackbarEvent.java │ │ │ └── ToastEvent.java │ │ ├── alfonzgraphics │ │ ├── GraphicsSampleActivity.java │ │ ├── GraphicsSampleFragment.java │ │ ├── GraphicsSampleView.java │ │ └── GraphicsSampleViewModel.java │ │ ├── alfonzmedia │ │ ├── MediaSampleActivity.java │ │ ├── MediaSampleFragment.java │ │ ├── MediaSampleView.java │ │ └── MediaSampleViewModel.java │ │ ├── alfonzrest │ │ ├── RestSampleActivity.java │ │ ├── RestSampleFragment.java │ │ ├── RestSampleRxViewModel.java │ │ ├── RestSampleView.java │ │ ├── RestSampleViewModel.java │ │ ├── entity │ │ │ ├── ErrorEntity.java │ │ │ ├── OwnerEntity.java │ │ │ └── RepoEntity.java │ │ └── rest │ │ │ ├── RestHttpException.java │ │ │ ├── RestHttpLogger.java │ │ │ ├── RestResponseHandler.java │ │ │ ├── RetrofitClient.java │ │ │ ├── http │ │ │ └── HeaderRequestInterceptor.java │ │ │ └── router │ │ │ ├── RepoRouter.java │ │ │ └── RepoRxRouter.java │ │ ├── alfonzrx │ │ ├── RxSampleActivity.java │ │ ├── RxSampleFragment.java │ │ ├── RxSampleView.java │ │ └── RxSampleViewModel.java │ │ ├── alfonzutility │ │ ├── UtilitySampleActivity.java │ │ ├── UtilitySampleFragment.java │ │ ├── UtilitySampleService.java │ │ ├── UtilitySampleView.java │ │ ├── UtilitySampleViewModel.java │ │ └── utility │ │ │ └── PermissionRationaleHandler.java │ │ └── alfonzview │ │ ├── ViewSampleActivity.java │ │ ├── ViewSampleFragment.java │ │ ├── ViewSampleView.java │ │ └── ViewSampleViewModel.java │ └── res │ ├── drawable-nodpi │ └── photo.png │ ├── drawable │ └── selector_clickable_item_bg.xml │ ├── layout │ ├── activity_adapter_sample.xml │ ├── activity_arch_sample.xml │ ├── activity_arch_sample_view_model.xml │ ├── activity_graphics_sample.xml │ ├── activity_media_sample.xml │ ├── activity_rest_sample.xml │ ├── activity_rx_sample.xml │ ├── activity_samples.xml │ ├── activity_utility_sample.xml │ ├── activity_view_sample.xml │ ├── fragment_adapter_sample_grid.xml │ ├── fragment_adapter_sample_list.xml │ ├── fragment_adapter_sample_list_bit_item.xml │ ├── fragment_adapter_sample_list_diff.xml │ ├── fragment_adapter_sample_list_message_item.xml │ ├── fragment_adapter_sample_list_number_item.xml │ ├── fragment_adapter_sample_pager.xml │ ├── fragment_adapter_sample_pager_bit_item.xml │ ├── fragment_adapter_sample_pager_message_item.xml │ ├── fragment_adapter_sample_pager_number_item.xml │ ├── fragment_arch_sample.xml │ ├── fragment_graphics_sample.xml │ ├── fragment_media_sample.xml │ ├── fragment_rest_sample.xml │ ├── fragment_rx_sample.xml │ ├── fragment_utility_sample.xml │ ├── fragment_view_sample.xml │ ├── placeholder_empty.xml │ ├── placeholder_offline.xml │ ├── placeholder_progress.xml │ └── toolbar.xml │ ├── menu │ └── activity_adapter_sample.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ └── values │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── settings.gradle └── utils.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.aar 4 | *.ap_ 5 | *.aab 6 | 7 | # Files for the ART/Dalvik VM 8 | *.dex 9 | 10 | # Java class files 11 | *.class 12 | 13 | # Generated files 14 | bin/ 15 | gen/ 16 | out/ 17 | # Uncomment the following line in case you need and you don't have the release build type files in your app 18 | # release/ 19 | 20 | # Gradle files 21 | .gradle/ 22 | build/ 23 | 24 | # Local configuration file (sdk path, etc) 25 | local.properties 26 | 27 | # Proguard folder generated by Eclipse 28 | proguard/ 29 | 30 | # Log Files 31 | *.log 32 | 33 | # Android Studio Navigation editor temp files 34 | .navigation/ 35 | 36 | # Android Studio captures folder 37 | captures/ 38 | 39 | # IntelliJ 40 | *.iml 41 | # Ignore the whole .idea folder 42 | .idea/ 43 | .idea/workspace.xml 44 | .idea/tasks.xml 45 | .idea/gradle.xml 46 | .idea/assetWizardSettings.xml 47 | .idea/dictionaries 48 | .idea/libraries 49 | # Android Studio 3 in .gitignore file. 50 | .idea/caches 51 | .idea/modules.xml 52 | # Comment next line if keeping position of elements in Navigation Editor is relevant for you 53 | .idea/navEditor.xml 54 | 55 | # Keystore files 56 | # Uncomment the following lines if you do not want to check your keystore files in. 57 | #*.jks 58 | #*.keystore 59 | 60 | # External native build folder generated in Android Studio 2.2 and later 61 | .externalNativeBuild 62 | .cxx/ 63 | 64 | # Google Services (e.g. APIs or Firebase) 65 | # google-services.json 66 | 67 | # Freeline 68 | freeline.py 69 | freeline/ 70 | freeline_project_description.json 71 | 72 | # fastlane 73 | fastlane/report.xml 74 | fastlane/Preview.html 75 | fastlane/screenshots 76 | fastlane/test_output 77 | fastlane/readme.md 78 | 79 | # Version control 80 | vcs.xml 81 | 82 | # lint 83 | lint/intermediates/ 84 | lint/generated/ 85 | lint/outputs/ 86 | lint/tmp/ 87 | # lint/reports/ 88 | 89 | # Mac 90 | .DS_Store 91 | -------------------------------------------------------------------------------- /alfonz-adapter/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.library" 2 | apply from: "../utils.gradle" 3 | 4 | ext { 5 | bintrayName = "alfonz-adapter" 6 | libraryName = "Alfonz-Adapter" 7 | artifact = "alfonz-adapter" 8 | } 9 | 10 | android { 11 | compileSdkVersion 30 12 | buildToolsVersion "30.0.3" 13 | 14 | defaultConfig { 15 | minSdkVersion 19 16 | targetSdkVersion 30 17 | versionCode getVersionCode(majorVersion, minorVersion, patchVersion, buildVersion) 18 | versionName getVersionName(majorVersion, minorVersion, patchVersion) 19 | } 20 | 21 | buildTypes { 22 | release { 23 | minifyEnabled false 24 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 25 | } 26 | } 27 | 28 | buildFeatures { 29 | dataBinding true 30 | } 31 | 32 | compileOptions { 33 | sourceCompatibility JavaVersion.VERSION_1_7 34 | targetCompatibility JavaVersion.VERSION_1_7 35 | } 36 | } 37 | 38 | dependencies { 39 | implementation fileTree(dir: "libs", include: ["*.jar"]) 40 | implementation "androidx.annotation:annotation:$androidxAnnotationVersion" 41 | implementation "androidx.recyclerview:recyclerview:$androidxRecyclerViewVersion" 42 | implementation "androidx.viewpager:viewpager:$androidxViewPagerVersion" 43 | 44 | } 45 | 46 | apply from: "../install.gradle" 47 | apply from: "../bintray.gradle" 48 | -------------------------------------------------------------------------------- /alfonz-adapter/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /alfonz-adapter/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /alfonz-adapter/src/main/java/org/alfonz/adapter/AdapterView.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.adapter; 2 | 3 | import androidx.lifecycle.LifecycleOwner; 4 | 5 | public interface AdapterView extends LifecycleOwner { 6 | } 7 | -------------------------------------------------------------------------------- /alfonz-adapter/src/main/java/org/alfonz/adapter/BaseDataBoundPagerAdapter.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.adapter; 2 | 3 | import android.view.LayoutInflater; 4 | import android.view.View; 5 | import android.view.ViewGroup; 6 | 7 | import androidx.annotation.LayoutRes; 8 | import androidx.annotation.NonNull; 9 | import androidx.databinding.DataBindingUtil; 10 | import androidx.databinding.ViewDataBinding; 11 | import androidx.viewpager.widget.PagerAdapter; 12 | 13 | public abstract class BaseDataBoundPagerAdapter extends PagerAdapter { 14 | private LayoutInflater mLayoutInflater; 15 | 16 | protected abstract void bindItem(T binding, int position); 17 | 18 | @LayoutRes 19 | public abstract int getItemLayoutId(int position); 20 | 21 | @NonNull 22 | @Override 23 | public Object instantiateItem(@NonNull ViewGroup container, int position) { 24 | if (mLayoutInflater == null) { 25 | mLayoutInflater = LayoutInflater.from(container.getContext()); 26 | } 27 | 28 | T binding = DataBindingUtil.inflate(mLayoutInflater, getItemLayoutId(position), container, false); 29 | bindItem(binding, position); 30 | binding.executePendingBindings(); 31 | container.addView(binding.getRoot()); 32 | return binding.getRoot(); 33 | } 34 | 35 | @Override 36 | public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) { 37 | container.removeView((View) object); 38 | } 39 | 40 | @Override 41 | public boolean isViewFromObject(@NonNull View view, @NonNull Object object) { 42 | return view == object; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /alfonz-adapter/src/main/java/org/alfonz/adapter/DataBoundListAdapter.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.adapter; 2 | 3 | import android.view.LayoutInflater; 4 | import android.view.ViewGroup; 5 | 6 | import androidx.annotation.LayoutRes; 7 | import androidx.annotation.NonNull; 8 | import androidx.recyclerview.widget.DiffUtil; 9 | import androidx.recyclerview.widget.ListAdapter; 10 | import androidx.recyclerview.widget.RecyclerView; 11 | 12 | public class DataBoundListAdapter extends ListAdapter> { 13 | private AdapterView mView; 14 | private ItemViewType mItemViewType; 15 | private LayoutInflater mLayoutInflater; 16 | 17 | public interface ItemViewType { 18 | int getLayoutId(Object item); 19 | } 20 | 21 | public DataBoundListAdapter(AdapterView view, @LayoutRes final int layoutId, @NonNull DiffUtil.ItemCallback diffCallback) { 22 | this(view, new ItemViewType() { 23 | @Override 24 | public int getLayoutId(Object item) { 25 | return layoutId; 26 | } 27 | }, diffCallback); 28 | } 29 | 30 | public DataBoundListAdapter(AdapterView view, ItemViewType itemViewType, @NonNull DiffUtil.ItemCallback diffCallback) { 31 | super(diffCallback); 32 | mView = view; 33 | mItemViewType = itemViewType; 34 | } 35 | 36 | @NonNull 37 | @Override 38 | public BaseDataBoundRecyclerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { 39 | if (mLayoutInflater == null) { 40 | mLayoutInflater = LayoutInflater.from(parent.getContext()); 41 | } 42 | 43 | return BaseDataBoundRecyclerViewHolder.create(mView, mLayoutInflater, parent, viewType); 44 | } 45 | 46 | @Override 47 | public void onBindViewHolder(@NonNull BaseDataBoundRecyclerViewHolder holder, int position) { 48 | holder.binding.setVariable(BR.view, mView); 49 | holder.binding.setVariable(BR.data, getItem(position)); 50 | holder.binding.executePendingBindings(); 51 | } 52 | 53 | @Override 54 | public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) { 55 | mLayoutInflater = null; 56 | } 57 | 58 | @Override 59 | public int getItemViewType(int position) { 60 | return mItemViewType.getLayoutId(getItem(position)); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /alfonz-adapter/src/main/java/org/alfonz/adapter/MultiDataBoundPagerAdapter.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.adapter; 2 | 3 | import android.view.View; 4 | 5 | import androidx.annotation.NonNull; 6 | import androidx.annotation.Nullable; 7 | import androidx.databinding.ObservableList; 8 | import androidx.databinding.ViewDataBinding; 9 | 10 | import org.alfonz.adapter.callback.OnPagerListChangedCallback; 11 | 12 | public abstract class MultiDataBoundPagerAdapter extends BaseDataBoundPagerAdapter { 13 | private AdapterView mView; 14 | private ObservableList[] mItems; 15 | 16 | @SuppressWarnings("unchecked") 17 | public MultiDataBoundPagerAdapter(AdapterView view, ObservableList... items) { 18 | mView = view; 19 | mItems = items; 20 | 21 | OnPagerListChangedCallback callback = new OnPagerListChangedCallback(this); 22 | for (ObservableList list : mItems) { 23 | list.addOnListChangedCallback(callback); 24 | } 25 | } 26 | 27 | @Override 28 | protected void bindItem(@NonNull ViewDataBinding binding, int position) { 29 | Object item = getItem(position); 30 | binding.setVariable(BR.view, mView); 31 | binding.setVariable(BR.data, item); 32 | binding.getRoot().setTag(item); 33 | } 34 | 35 | @Override 36 | public int getCount() { 37 | int size = 0; 38 | for (ObservableList list : mItems) { 39 | size += list.size(); 40 | } 41 | return size; 42 | } 43 | 44 | @Override 45 | public int getItemPosition(@NonNull Object object) { 46 | Object item = ((View) object).getTag(); 47 | if (mItems != null) { 48 | int counter = 0; 49 | for (ObservableList list : mItems) { 50 | for (int i = 0; i < list.size(); i++) { 51 | if (item == list.get(i)) { 52 | return counter; 53 | } 54 | counter++; 55 | } 56 | } 57 | } 58 | return POSITION_NONE; 59 | } 60 | 61 | @Nullable 62 | public Object getItem(int position) { 63 | int counter = 0; 64 | for (ObservableList list : mItems) { 65 | if (position - counter - list.size() < 0) { 66 | int index = position - counter; 67 | return list.get(index); 68 | } 69 | counter += list.size(); 70 | } 71 | return null; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /alfonz-adapter/src/main/java/org/alfonz/adapter/MultiDataBoundRecyclerAdapter.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.adapter; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.annotation.Nullable; 5 | import androidx.databinding.ObservableList; 6 | import androidx.recyclerview.widget.RecyclerView; 7 | 8 | import org.alfonz.adapter.callback.RecyclerListChangedCallbackHolder; 9 | 10 | import java.util.List; 11 | 12 | public abstract class MultiDataBoundRecyclerAdapter extends BaseDataBoundRecyclerAdapter { 13 | private AdapterView mView; 14 | private ObservableList[] mItems; 15 | private RecyclerListChangedCallbackHolder mCallbackHolder = new RecyclerListChangedCallbackHolder(); 16 | 17 | public MultiDataBoundRecyclerAdapter(AdapterView view, ObservableList... items) { 18 | mView = view; 19 | mItems = items; 20 | } 21 | 22 | @Override 23 | protected void bindItem(@NonNull BaseDataBoundRecyclerViewHolder holder, int position, List payloads) { 24 | holder.binding.setVariable(BR.view, mView); 25 | holder.binding.setVariable(BR.data, getItem(position)); 26 | } 27 | 28 | @Override 29 | public int getItemCount() { 30 | int size = 0; 31 | for (ObservableList list : mItems) { 32 | size += list.size(); 33 | } 34 | return size; 35 | } 36 | 37 | @Override 38 | public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) { 39 | super.onAttachedToRecyclerView(recyclerView); 40 | mCallbackHolder.register(this, mItems); 41 | } 42 | 43 | @Override 44 | public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) { 45 | super.onDetachedFromRecyclerView(recyclerView); 46 | mCallbackHolder.unregister(mItems); 47 | } 48 | 49 | @Nullable 50 | public Object getItem(int position) { 51 | int counter = 0; 52 | for (ObservableList list : mItems) { 53 | if (position - counter - list.size() < 0) { 54 | int index = position - counter; 55 | return list.get(index); 56 | } 57 | counter += list.size(); 58 | } 59 | return null; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /alfonz-adapter/src/main/java/org/alfonz/adapter/MultiMapDataBoundRecyclerAdapter.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.adapter; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.annotation.Nullable; 5 | import androidx.databinding.ObservableArrayMap; 6 | import androidx.recyclerview.widget.RecyclerView; 7 | 8 | import org.alfonz.adapter.callback.RecyclerMapChangedCallbackHolder; 9 | 10 | import java.util.List; 11 | 12 | public abstract class MultiMapDataBoundRecyclerAdapter extends BaseDataBoundRecyclerAdapter { 13 | private AdapterView mView; 14 | private ObservableArrayMap[] mItems; 15 | private RecyclerMapChangedCallbackHolder mCallbackHolder = new RecyclerMapChangedCallbackHolder(); 16 | 17 | public MultiMapDataBoundRecyclerAdapter(AdapterView view, ObservableArrayMap... items) { 18 | mView = view; 19 | mItems = items; 20 | } 21 | 22 | @Override 23 | protected void bindItem(@NonNull BaseDataBoundRecyclerViewHolder holder, int position, List payloads) { 24 | holder.binding.setVariable(BR.view, mView); 25 | holder.binding.setVariable(BR.data, getItem(position)); 26 | } 27 | 28 | @Override 29 | public int getItemCount() { 30 | int size = 0; 31 | for (ObservableArrayMap map : mItems) { 32 | size += map.size(); 33 | } 34 | return size; 35 | } 36 | 37 | @Override 38 | public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) { 39 | super.onAttachedToRecyclerView(recyclerView); 40 | mCallbackHolder.register(this, mItems); 41 | } 42 | 43 | @Override 44 | public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) { 45 | super.onDetachedFromRecyclerView(recyclerView); 46 | mCallbackHolder.unregister(mItems); 47 | } 48 | 49 | @Nullable 50 | public Object getItem(int position) { 51 | int counter = 0; 52 | for (ObservableArrayMap map : mItems) { 53 | if (position - counter - map.size() < 0) { 54 | int index = position - counter; 55 | return map.valueAt(index); 56 | } 57 | counter += map.size(); 58 | } 59 | return null; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /alfonz-adapter/src/main/java/org/alfonz/adapter/SimpleDataBoundPagerAdapter.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.adapter; 2 | 3 | import android.view.View; 4 | 5 | import androidx.annotation.LayoutRes; 6 | import androidx.annotation.NonNull; 7 | import androidx.databinding.ObservableList; 8 | import androidx.databinding.ViewDataBinding; 9 | 10 | import org.alfonz.adapter.callback.OnPagerListChangedCallback; 11 | 12 | public class SimpleDataBoundPagerAdapter extends BaseDataBoundPagerAdapter { 13 | @LayoutRes private int mLayoutId; 14 | private AdapterView mView; 15 | private ObservableList mItems; 16 | 17 | @SuppressWarnings("unchecked") 18 | public SimpleDataBoundPagerAdapter(@LayoutRes int layoutId, AdapterView view, ObservableList items) { 19 | mLayoutId = layoutId; 20 | mView = view; 21 | mItems = items; 22 | 23 | mItems.addOnListChangedCallback(new OnPagerListChangedCallback(this)); 24 | } 25 | 26 | @Override 27 | protected void bindItem(@NonNull ViewDataBinding binding, int position) { 28 | Object item = mItems.get(position); 29 | binding.setVariable(BR.view, mView); 30 | binding.setVariable(BR.data, item); 31 | binding.getRoot().setTag(item); 32 | } 33 | 34 | @Override 35 | public int getItemLayoutId(int position) { 36 | return mLayoutId; 37 | } 38 | 39 | @Override 40 | public int getCount() { 41 | return mItems.size(); 42 | } 43 | 44 | @Override 45 | public int getItemPosition(@NonNull Object object) { 46 | Object item = ((View) object).getTag(); 47 | if (mItems != null) { 48 | for (int i = 0; i < mItems.size(); i++) { 49 | if (item == mItems.get(i)) { 50 | return i; 51 | } 52 | } 53 | } 54 | return POSITION_NONE; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /alfonz-adapter/src/main/java/org/alfonz/adapter/SimpleDataBoundRecyclerAdapter.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.adapter; 2 | 3 | import androidx.annotation.LayoutRes; 4 | import androidx.annotation.NonNull; 5 | import androidx.databinding.ObservableList; 6 | import androidx.recyclerview.widget.RecyclerView; 7 | 8 | import org.alfonz.adapter.callback.RecyclerListChangedCallbackHolder; 9 | 10 | import java.util.List; 11 | 12 | public class SimpleDataBoundRecyclerAdapter extends BaseDataBoundRecyclerAdapter { 13 | @LayoutRes private int mLayoutId; 14 | private AdapterView mView; 15 | private ObservableList mItems; 16 | private RecyclerListChangedCallbackHolder mCallbackHolder = new RecyclerListChangedCallbackHolder(); 17 | 18 | public SimpleDataBoundRecyclerAdapter(@LayoutRes int layoutId, AdapterView view, ObservableList items) { 19 | mLayoutId = layoutId; 20 | mView = view; 21 | mItems = items; 22 | } 23 | 24 | @Override 25 | protected void bindItem(@NonNull BaseDataBoundRecyclerViewHolder holder, int position, List payloads) { 26 | holder.binding.setVariable(BR.view, mView); 27 | holder.binding.setVariable(BR.data, mItems.get(position)); 28 | } 29 | 30 | @Override 31 | public int getItemLayoutId(int position) { 32 | return mLayoutId; 33 | } 34 | 35 | @Override 36 | public int getItemCount() { 37 | return mItems.size(); 38 | } 39 | 40 | @Override 41 | public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) { 42 | super.onAttachedToRecyclerView(recyclerView); 43 | mCallbackHolder.register(this, mItems); 44 | } 45 | 46 | @Override 47 | public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) { 48 | super.onDetachedFromRecyclerView(recyclerView); 49 | mCallbackHolder.unregister(mItems); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /alfonz-adapter/src/main/java/org/alfonz/adapter/SimpleMapDataBoundRecyclerAdapter.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.adapter; 2 | 3 | import androidx.annotation.LayoutRes; 4 | import androidx.annotation.NonNull; 5 | import androidx.databinding.ObservableArrayMap; 6 | import androidx.recyclerview.widget.RecyclerView; 7 | 8 | import org.alfonz.adapter.callback.RecyclerMapChangedCallbackHolder; 9 | 10 | import java.util.List; 11 | 12 | public class SimpleMapDataBoundRecyclerAdapter extends BaseDataBoundRecyclerAdapter { 13 | @LayoutRes private int mLayoutId; 14 | private AdapterView mView; 15 | private ObservableArrayMap mItems; 16 | private RecyclerMapChangedCallbackHolder mCallbackHolder = new RecyclerMapChangedCallbackHolder(); 17 | 18 | public SimpleMapDataBoundRecyclerAdapter(@LayoutRes int layoutId, AdapterView view, ObservableArrayMap items) { 19 | mLayoutId = layoutId; 20 | mView = view; 21 | mItems = items; 22 | } 23 | 24 | @Override 25 | protected void bindItem(@NonNull BaseDataBoundRecyclerViewHolder holder, int position, List payloads) { 26 | holder.binding.setVariable(BR.view, mView); 27 | holder.binding.setVariable(BR.data, mItems.valueAt(position)); 28 | } 29 | 30 | @Override 31 | public int getItemLayoutId(int position) { 32 | return mLayoutId; 33 | } 34 | 35 | @Override 36 | public int getItemCount() { 37 | return mItems.size(); 38 | } 39 | 40 | @Override 41 | public void onAttachedToRecyclerView(@NonNull RecyclerView recyclerView) { 42 | super.onAttachedToRecyclerView(recyclerView); 43 | mCallbackHolder.register(this, mItems); 44 | } 45 | 46 | @Override 47 | public void onDetachedFromRecyclerView(@NonNull RecyclerView recyclerView) { 48 | super.onDetachedFromRecyclerView(recyclerView); 49 | mCallbackHolder.unregister(mItems); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /alfonz-adapter/src/main/java/org/alfonz/adapter/callback/OnPagerListChangedCallback.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.adapter.callback; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.databinding.ObservableList; 5 | 6 | import org.alfonz.adapter.BaseDataBoundPagerAdapter; 7 | 8 | import java.lang.ref.WeakReference; 9 | 10 | public class OnPagerListChangedCallback> extends ObservableList.OnListChangedCallback { 11 | @NonNull private final WeakReference mAdapter; 12 | 13 | public OnPagerListChangedCallback(BaseDataBoundPagerAdapter adapter) { 14 | mAdapter = new WeakReference<>(adapter); 15 | } 16 | 17 | @Override 18 | public void onChanged(T sender) { 19 | onUpdate(sender); 20 | } 21 | 22 | @Override 23 | public void onItemRangeChanged(T sender, int positionStart, int itemCount) { 24 | onUpdate(sender); 25 | } 26 | 27 | @Override 28 | public void onItemRangeInserted(T sender, int positionStart, int itemCount) { 29 | onUpdate(sender); 30 | } 31 | 32 | @Override 33 | public void onItemRangeMoved(T sender, int fromPosition, int toPosition, int itemCount) { 34 | onUpdate(sender); 35 | } 36 | 37 | @Override 38 | public void onItemRangeRemoved(T sender, int positionStart, int itemCount) { 39 | onUpdate(sender); 40 | } 41 | 42 | @SuppressWarnings("unchecked") 43 | private void onUpdate(T observableList) { 44 | if (mAdapter.get() != null) { 45 | mAdapter.get().notifyDataSetChanged(); 46 | } else { 47 | observableList.removeOnListChangedCallback((ObservableList.OnListChangedCallback) this); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /alfonz-adapter/src/main/java/org/alfonz/adapter/callback/OnRecyclerListChangedCallback.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.adapter.callback; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.databinding.ObservableList; 5 | 6 | import org.alfonz.adapter.BaseDataBoundRecyclerAdapter; 7 | 8 | import java.lang.ref.WeakReference; 9 | 10 | public class OnRecyclerListChangedCallback> extends ObservableList.OnListChangedCallback { 11 | @NonNull private final WeakReference mAdapter; 12 | 13 | public OnRecyclerListChangedCallback(BaseDataBoundRecyclerAdapter adapter) { 14 | mAdapter = new WeakReference<>(adapter); 15 | } 16 | 17 | @Override 18 | public void onChanged(T sender) { 19 | if (mAdapter.get() != null) { 20 | mAdapter.get().notifyDataSetChanged(); 21 | } else { 22 | removeCallback(sender); 23 | } 24 | } 25 | 26 | @Override 27 | public void onItemRangeChanged(T sender, int positionStart, int itemCount) { 28 | if (mAdapter.get() != null) { 29 | mAdapter.get().notifyItemRangeChanged(positionStart, itemCount); 30 | } else { 31 | removeCallback(sender); 32 | } 33 | } 34 | 35 | @Override 36 | public void onItemRangeInserted(T sender, int positionStart, int itemCount) { 37 | if (mAdapter.get() != null) { 38 | mAdapter.get().notifyItemRangeInserted(positionStart, itemCount); 39 | } else { 40 | removeCallback(sender); 41 | } 42 | } 43 | 44 | @Override 45 | public void onItemRangeMoved(T sender, int fromPosition, int toPosition, int itemCount) { 46 | if (mAdapter.get() != null) { 47 | for (int i = 0; i < itemCount; i++) { 48 | mAdapter.get().notifyItemMoved(fromPosition + i, toPosition + i); 49 | } 50 | } else { 51 | removeCallback(sender); 52 | } 53 | } 54 | 55 | @Override 56 | public void onItemRangeRemoved(T sender, int positionStart, int itemCount) { 57 | if (mAdapter.get() != null) { 58 | mAdapter.get().notifyItemRangeRemoved(positionStart, itemCount); 59 | } else { 60 | removeCallback(sender); 61 | } 62 | } 63 | 64 | @SuppressWarnings("unchecked") 65 | private void removeCallback(T observableList) { 66 | observableList.removeOnListChangedCallback((ObservableList.OnListChangedCallback) this); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /alfonz-adapter/src/main/java/org/alfonz/adapter/callback/OnRecyclerMapChangedCallback.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.adapter.callback; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.databinding.ObservableMap; 5 | 6 | import org.alfonz.adapter.BaseDataBoundRecyclerAdapter; 7 | 8 | import java.lang.ref.WeakReference; 9 | 10 | public class OnRecyclerMapChangedCallback, K, V> extends ObservableMap.OnMapChangedCallback { 11 | @NonNull private final WeakReference mAdapter; 12 | 13 | public OnRecyclerMapChangedCallback(BaseDataBoundRecyclerAdapter adapter) { 14 | mAdapter = new WeakReference<>(adapter); 15 | } 16 | 17 | @Override 18 | public void onMapChanged(T sender, K key) { 19 | if (mAdapter.get() != null) { 20 | mAdapter.get().notifyDataSetChanged(); 21 | } else { 22 | sender.removeOnMapChangedCallback(this); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /alfonz-adapter/src/main/java/org/alfonz/adapter/callback/RecyclerListChangedCallbackHolder.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.adapter.callback; 2 | 3 | import androidx.databinding.ObservableList; 4 | 5 | import org.alfonz.adapter.BaseDataBoundRecyclerAdapter; 6 | 7 | public class RecyclerListChangedCallbackHolder { 8 | private OnRecyclerListChangedCallback mCallback; 9 | 10 | @SuppressWarnings("unchecked") 11 | public void register(BaseDataBoundRecyclerAdapter adapter, ObservableList items) { 12 | if (mCallback == null) { 13 | mCallback = new OnRecyclerListChangedCallback(adapter); 14 | items.addOnListChangedCallback(mCallback); 15 | } 16 | } 17 | 18 | @SuppressWarnings("unchecked") 19 | public void register(BaseDataBoundRecyclerAdapter adapter, ObservableList[] items) { 20 | if (mCallback == null) { 21 | mCallback = new OnRecyclerListChangedCallback(adapter); 22 | for (ObservableList list : items) { 23 | list.addOnListChangedCallback(mCallback); 24 | } 25 | } 26 | } 27 | 28 | @SuppressWarnings("unchecked") 29 | public void unregister(ObservableList items) { 30 | if (mCallback != null) { 31 | items.removeOnListChangedCallback(mCallback); 32 | mCallback = null; 33 | } 34 | } 35 | 36 | @SuppressWarnings("unchecked") 37 | public void unregister(ObservableList[] items) { 38 | if (mCallback != null) { 39 | for (ObservableList list : items) { 40 | list.removeOnListChangedCallback(mCallback); 41 | } 42 | mCallback = null; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /alfonz-adapter/src/main/java/org/alfonz/adapter/callback/RecyclerMapChangedCallbackHolder.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.adapter.callback; 2 | 3 | import androidx.databinding.ObservableMap; 4 | 5 | import org.alfonz.adapter.BaseDataBoundRecyclerAdapter; 6 | 7 | public class RecyclerMapChangedCallbackHolder { 8 | private OnRecyclerMapChangedCallback mCallback; 9 | 10 | @SuppressWarnings("unchecked") 11 | public void register(BaseDataBoundRecyclerAdapter adapter, ObservableMap items) { 12 | if (mCallback == null) { 13 | mCallback = new OnRecyclerMapChangedCallback(adapter); 14 | items.addOnMapChangedCallback(mCallback); 15 | } 16 | } 17 | 18 | @SuppressWarnings("unchecked") 19 | public void register(BaseDataBoundRecyclerAdapter adapter, ObservableMap[] items) { 20 | if (mCallback == null) { 21 | mCallback = new OnRecyclerMapChangedCallback(adapter); 22 | for (ObservableMap map : items) { 23 | map.addOnMapChangedCallback(mCallback); 24 | } 25 | } 26 | } 27 | 28 | @SuppressWarnings("unchecked") 29 | public void unregister(ObservableMap items) { 30 | if (mCallback != null) { 31 | items.removeOnMapChangedCallback(mCallback); 32 | mCallback = null; 33 | } 34 | } 35 | 36 | @SuppressWarnings("unchecked") 37 | public void unregister(ObservableMap[] items) { 38 | if (mCallback != null) { 39 | for (ObservableMap map : items) { 40 | map.removeOnMapChangedCallback(mCallback); 41 | } 42 | mCallback = null; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /alfonz-adapter/src/main/res/layout/binding_variables.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 9 | 12 | 15 | 16 | 17 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /alfonz-arch/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.library" 2 | apply from: "../utils.gradle" 3 | 4 | ext { 5 | bintrayName = "alfonz-arch" 6 | libraryName = "Alfonz-Arch" 7 | artifact = "alfonz-arch" 8 | } 9 | 10 | android { 11 | compileSdkVersion 30 12 | buildToolsVersion "30.0.3" 13 | 14 | defaultConfig { 15 | minSdkVersion 19 16 | targetSdkVersion 30 17 | versionCode getVersionCode(majorVersion, minorVersion, patchVersion, buildVersion) 18 | versionName getVersionName(majorVersion, minorVersion, patchVersion) 19 | } 20 | 21 | buildTypes { 22 | release { 23 | minifyEnabled false 24 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 25 | } 26 | } 27 | 28 | buildFeatures { 29 | dataBinding true 30 | } 31 | 32 | compileOptions { 33 | sourceCompatibility JavaVersion.VERSION_1_7 34 | targetCompatibility JavaVersion.VERSION_1_7 35 | } 36 | } 37 | 38 | dependencies { 39 | implementation fileTree(dir: "libs", include: ["*.jar"]) 40 | implementation "androidx.annotation:annotation:$androidxAnnotationVersion" 41 | implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion" 42 | implementation "androidx.fragment:fragment:$androidxFragmentVersion" 43 | implementation "androidx.lifecycle:lifecycle-extensions:$androidxLifecycleVersion" 44 | implementation "androidx.lifecycle:lifecycle-runtime:$androidxLifecycleVersion" 45 | annotationProcessor "androidx.lifecycle:lifecycle-common-java8:2.3.0" 46 | } 47 | 48 | apply from: "../install.gradle" 49 | apply from: "../bintray.gradle" 50 | -------------------------------------------------------------------------------- /alfonz-arch/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /alfonz-arch/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /alfonz-arch/src/main/java/org/alfonz/arch/AlfonzBindingActivity.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.arch; 2 | 3 | import android.os.Bundle; 4 | import android.view.LayoutInflater; 5 | 6 | import androidx.annotation.NonNull; 7 | import androidx.databinding.ViewDataBinding; 8 | 9 | public abstract class AlfonzBindingActivity extends AlfonzActivity implements AlfonzView { 10 | private T mViewModel; 11 | private B mBinding; 12 | 13 | public abstract T setupViewModel(); 14 | public abstract B inflateBindingLayout(@NonNull LayoutInflater inflater); 15 | 16 | @Override 17 | public void onCreate(Bundle savedInstanceState) { 18 | super.onCreate(savedInstanceState); 19 | mViewModel = setupViewModel(); 20 | mBinding = setupBinding(getLayoutInflater()); 21 | setContentView(mBinding.getRoot()); 22 | } 23 | 24 | public T getViewModel() { 25 | return mViewModel; 26 | } 27 | 28 | public B getBinding() { 29 | return mBinding; 30 | } 31 | 32 | private B setupBinding(@NonNull LayoutInflater inflater) { 33 | B binding = inflateBindingLayout(inflater); 34 | binding.setVariable(BR.view, this); 35 | binding.setVariable(BR.viewModel, getViewModel()); 36 | binding.setLifecycleOwner(this); 37 | return binding; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /alfonz-arch/src/main/java/org/alfonz/arch/AlfonzBindingFragment.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.arch; 2 | 3 | import android.os.Bundle; 4 | import android.view.LayoutInflater; 5 | import android.view.View; 6 | import android.view.ViewGroup; 7 | 8 | import androidx.annotation.NonNull; 9 | import androidx.databinding.ViewDataBinding; 10 | 11 | public abstract class AlfonzBindingFragment extends AlfonzFragment { 12 | private B mBinding; 13 | 14 | public abstract B inflateBindingLayout(@NonNull LayoutInflater inflater); 15 | 16 | @Override 17 | public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 18 | super.onCreateView(inflater, container, savedInstanceState); 19 | mBinding = setupBinding(inflater); 20 | return mBinding.getRoot(); 21 | } 22 | 23 | public B getBinding() { 24 | return mBinding; 25 | } 26 | 27 | private B setupBinding(@NonNull LayoutInflater inflater) { 28 | B binding = inflateBindingLayout(inflater); 29 | binding.setVariable(BR.view, this); 30 | binding.setVariable(BR.viewModel, getViewModel()); 31 | binding.setLifecycleOwner(this); 32 | return binding; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /alfonz-arch/src/main/java/org/alfonz/arch/AlfonzFragment.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.arch; 2 | 3 | import android.os.Bundle; 4 | 5 | import androidx.annotation.Nullable; 6 | import androidx.fragment.app.Fragment; 7 | 8 | public abstract class AlfonzFragment extends Fragment implements AlfonzView { 9 | private T mViewModel; 10 | 11 | public abstract T setupViewModel(); 12 | 13 | @Override 14 | public void onCreate(Bundle savedInstanceState) { 15 | super.onCreate(savedInstanceState); 16 | mViewModel = setupViewModel(); 17 | } 18 | 19 | public boolean onBackPressed() { 20 | // return true if back press was handled 21 | return false; 22 | } 23 | 24 | public T getViewModel() { 25 | return mViewModel; 26 | } 27 | 28 | @Nullable 29 | public AlfonzActivity getAlfonzActivity() { 30 | return (AlfonzActivity) getActivity(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /alfonz-arch/src/main/java/org/alfonz/arch/AlfonzView.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.arch; 2 | 3 | public interface AlfonzView { 4 | } 5 | -------------------------------------------------------------------------------- /alfonz-arch/src/main/java/org/alfonz/arch/AlfonzViewModel.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.arch; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.databinding.Observable; 5 | import androidx.databinding.PropertyChangeRegistry; 6 | import androidx.lifecycle.LifecycleOwner; 7 | import androidx.lifecycle.ViewModel; 8 | 9 | import org.alfonz.arch.event.Event; 10 | import org.alfonz.arch.event.EventObserver; 11 | import org.alfonz.arch.event.LiveBus; 12 | 13 | public abstract class AlfonzViewModel extends ViewModel implements Observable { 14 | private transient PropertyChangeRegistry mObservableCallbacks; 15 | private LiveBus mLiveBus = new LiveBus(); 16 | 17 | @Override 18 | public synchronized void addOnPropertyChangedCallback(@NonNull OnPropertyChangedCallback callback) { 19 | if (mObservableCallbacks == null) { 20 | mObservableCallbacks = new PropertyChangeRegistry(); 21 | } 22 | mObservableCallbacks.add(callback); 23 | } 24 | 25 | @Override 26 | public synchronized void removeOnPropertyChangedCallback(@NonNull OnPropertyChangedCallback callback) { 27 | if (mObservableCallbacks != null) { 28 | mObservableCallbacks.remove(callback); 29 | } 30 | } 31 | 32 | public synchronized void notifyChange() { 33 | if (mObservableCallbacks != null) { 34 | mObservableCallbacks.notifyCallbacks(this, 0, null); 35 | } 36 | } 37 | 38 | public void notifyPropertyChanged(int fieldId) { 39 | if (mObservableCallbacks != null) { 40 | mObservableCallbacks.notifyCallbacks(this, fieldId, null); 41 | } 42 | } 43 | 44 | public void observeEvent(@NonNull LifecycleOwner lifecycleOwner, @NonNull Class eventClass, @NonNull EventObserver eventObserver) { 45 | mLiveBus.observe(lifecycleOwner, eventClass, eventObserver); 46 | } 47 | 48 | public void removeEventObservers(@NonNull LifecycleOwner lifecycleOwner, @NonNull Class eventClass) { 49 | mLiveBus.removeObservers(lifecycleOwner, eventClass); 50 | } 51 | 52 | public void sendEvent(@NonNull T event) { 53 | mLiveBus.send(event); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /alfonz-arch/src/main/java/org/alfonz/arch/bundle/AlfonzBundleViewModel.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.arch.bundle; 2 | 3 | import android.app.Application; 4 | import android.os.Bundle; 5 | 6 | import androidx.annotation.NonNull; 7 | 8 | import org.alfonz.arch.AlfonzViewModel; 9 | 10 | public abstract class AlfonzBundleViewModel extends AlfonzViewModel { 11 | private Application mApplication; 12 | private Bundle mBundle; 13 | 14 | public AlfonzBundleViewModel() { 15 | } 16 | 17 | public AlfonzBundleViewModel(@NonNull Bundle bundle) { 18 | mBundle = bundle; 19 | } 20 | 21 | public AlfonzBundleViewModel(@NonNull Application application, @NonNull Bundle bundle) { 22 | mApplication = application; 23 | mBundle = bundle; 24 | } 25 | 26 | public T getApplication() { 27 | // noinspection unchecked 28 | return (T) mApplication; 29 | } 30 | 31 | public Bundle getBundle() { 32 | return mBundle; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /alfonz-arch/src/main/java/org/alfonz/arch/bundle/AlfonzBundleViewModelFactory.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.arch.bundle; 2 | 3 | import android.app.Application; 4 | import android.os.Bundle; 5 | 6 | import androidx.annotation.NonNull; 7 | import androidx.lifecycle.ViewModel; 8 | import androidx.lifecycle.ViewModelProvider; 9 | 10 | import org.alfonz.arch.AlfonzActivity; 11 | import org.alfonz.arch.AlfonzFragment; 12 | 13 | import java.lang.reflect.InvocationTargetException; 14 | 15 | public class AlfonzBundleViewModelFactory extends ViewModelProvider.NewInstanceFactory { 16 | private final Application mApplication; 17 | private final Bundle mBundle; 18 | 19 | public AlfonzBundleViewModelFactory() { 20 | mApplication = null; 21 | mBundle = null; 22 | } 23 | 24 | public AlfonzBundleViewModelFactory(@NonNull AlfonzActivity activity) { 25 | mApplication = null; 26 | mBundle = activity.getIntent().getExtras(); 27 | } 28 | 29 | public AlfonzBundleViewModelFactory(@NonNull AlfonzFragment fragment) { 30 | mApplication = null; 31 | mBundle = fragment.getArguments(); 32 | } 33 | 34 | public AlfonzBundleViewModelFactory(@NonNull Bundle bundle) { 35 | mApplication = null; 36 | mBundle = bundle; 37 | } 38 | 39 | public AlfonzBundleViewModelFactory(@NonNull Application application, @NonNull AlfonzActivity activity) { 40 | mApplication = application; 41 | mBundle = activity.getIntent().getExtras(); 42 | } 43 | 44 | public AlfonzBundleViewModelFactory(@NonNull Application application, @NonNull AlfonzFragment fragment) { 45 | mApplication = application; 46 | mBundle = fragment.getArguments(); 47 | } 48 | 49 | public AlfonzBundleViewModelFactory(@NonNull Application application, @NonNull Bundle bundle) { 50 | mApplication = application; 51 | mBundle = bundle; 52 | } 53 | 54 | @NonNull 55 | @Override 56 | public T create(@NonNull Class modelClass) { 57 | try { 58 | if (mApplication != null && mBundle != null) { 59 | return modelClass.getDeclaredConstructor(Application.class, Bundle.class).newInstance(mApplication, mBundle); 60 | } else if (mBundle != null) { 61 | return modelClass.getDeclaredConstructor(Bundle.class).newInstance(mBundle); 62 | } else { 63 | return modelClass.getDeclaredConstructor().newInstance(); 64 | } 65 | } catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) { 66 | throw new RuntimeException("Cannot create an instance of " + modelClass, e); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /alfonz-arch/src/main/java/org/alfonz/arch/event/Event.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.arch.event; 2 | 3 | public abstract class Event { 4 | } 5 | -------------------------------------------------------------------------------- /alfonz-arch/src/main/java/org/alfonz/arch/event/EventObserver.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.arch.event; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.lifecycle.Observer; 5 | 6 | public interface EventObserver extends Observer { 7 | void onChanged(@NonNull T event); 8 | } 9 | -------------------------------------------------------------------------------- /alfonz-arch/src/main/java/org/alfonz/arch/event/LiveBus.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.arch.event; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.collection.ArrayMap; 5 | import androidx.lifecycle.LifecycleOwner; 6 | 7 | import java.util.Map; 8 | 9 | public class LiveBus { 10 | private final Map, LiveEvent> mEventMap; 11 | 12 | public LiveBus() { 13 | mEventMap = new ArrayMap<>(); 14 | } 15 | 16 | @SuppressWarnings("unchecked") 17 | public void observe(@NonNull LifecycleOwner lifecycleOwner, @NonNull Class eventClass, @NonNull EventObserver eventObserver) { 18 | LiveEvent liveEvent = (LiveEvent) mEventMap.get(eventClass); 19 | if (liveEvent == null) { 20 | liveEvent = initLiveEvent(eventClass); 21 | } 22 | liveEvent.observe(lifecycleOwner, eventObserver); 23 | } 24 | 25 | @SuppressWarnings("unchecked") 26 | public void removeObservers(@NonNull LifecycleOwner lifecycleOwner, @NonNull Class eventClass) { 27 | LiveEvent liveEvent = (LiveEvent) mEventMap.get(eventClass); 28 | if (liveEvent != null) { 29 | liveEvent.removeObservers(lifecycleOwner); 30 | } 31 | } 32 | 33 | @SuppressWarnings("unchecked") 34 | public void send(@NonNull T event) { 35 | LiveEvent liveEvent = (LiveEvent) mEventMap.get(event.getClass()); 36 | if (liveEvent == null) { 37 | liveEvent = initLiveEvent((Class) event.getClass()); 38 | } 39 | liveEvent.setValue(event); 40 | } 41 | 42 | @NonNull 43 | private LiveEvent initLiveEvent(Class eventClass) { 44 | LiveEvent liveEvent = new LiveEvent<>(); 45 | mEventMap.put(eventClass, liveEvent); 46 | return liveEvent; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /alfonz-arch/src/main/java/org/alfonz/arch/event/LiveEvent.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.arch.event; 2 | 3 | import androidx.annotation.MainThread; 4 | import androidx.annotation.NonNull; 5 | import androidx.annotation.Nullable; 6 | import androidx.lifecycle.LifecycleOwner; 7 | import androidx.lifecycle.MutableLiveData; 8 | import androidx.lifecycle.Observer; 9 | 10 | import java.util.concurrent.atomic.AtomicBoolean; 11 | 12 | // source: https://github.com/googlesamples/android-architecture-components/issues/63 13 | public class LiveEvent extends MutableLiveData { 14 | private final AtomicBoolean mPending = new AtomicBoolean(false); 15 | 16 | @MainThread 17 | public void observe(@NonNull LifecycleOwner lifecycleOwner, @NonNull final Observer observer) { 18 | // observe the internal MutableLiveData 19 | super.observe(lifecycleOwner, new Observer() { 20 | @Override 21 | public void onChanged(@Nullable T value) { 22 | if (mPending.compareAndSet(true, false)) { 23 | observer.onChanged(value); 24 | } 25 | } 26 | }); 27 | } 28 | 29 | @MainThread 30 | public void setValue(@Nullable T value) { 31 | mPending.set(true); 32 | super.setValue(value); 33 | } 34 | 35 | @MainThread 36 | public void call() { 37 | setValue(null); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /alfonz-arch/src/main/java/org/alfonz/arch/utility/BindingUtility.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.arch.utility; 2 | 3 | import android.graphics.Bitmap; 4 | import android.view.View; 5 | import android.widget.ImageView; 6 | 7 | import androidx.annotation.NonNull; 8 | import androidx.databinding.BindingAdapter; 9 | import androidx.databinding.BindingConversion; 10 | 11 | public final class BindingUtility { 12 | private BindingUtility() {} 13 | 14 | @BindingAdapter({"onClick"}) 15 | public static void setOnClick(@NonNull View view, View.OnClickListener listener) { 16 | view.setOnClickListener(listener); 17 | } 18 | 19 | @BindingAdapter({"onLongClick"}) 20 | public static void setOnLongClick(@NonNull View view, View.OnLongClickListener listener) { 21 | view.setOnLongClickListener(listener); 22 | } 23 | 24 | @BindingAdapter({"visible"}) 25 | public static void setVisible(@NonNull View view, boolean visible) { 26 | view.setVisibility(visible ? View.VISIBLE : View.GONE); 27 | } 28 | 29 | @BindingAdapter({"invisible"}) 30 | public static void setInvisible(@NonNull View view, boolean invisible) { 31 | view.setVisibility(invisible ? View.INVISIBLE : View.VISIBLE); 32 | } 33 | 34 | @BindingAdapter({"gone"}) 35 | public static void setGone(@NonNull View view, boolean gone) { 36 | view.setVisibility(gone ? View.GONE : View.VISIBLE); 37 | } 38 | 39 | @BindingAdapter({"imageBitmap"}) 40 | public static void setImageBitmap(@NonNull ImageView imageView, Bitmap bitmap) { 41 | imageView.setImageBitmap(bitmap); 42 | } 43 | 44 | @BindingConversion 45 | public static int convertBooleanToVisibility(boolean visible) { 46 | return visible ? View.VISIBLE : View.GONE; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /alfonz-arch/src/main/java/org/alfonz/arch/widget/ToolbarIndicator.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.arch.widget; 2 | 3 | import android.content.Context; 4 | import android.content.res.TypedArray; 5 | import android.graphics.PorterDuff; 6 | import android.graphics.PorterDuffColorFilter; 7 | import android.graphics.drawable.Drawable; 8 | import android.os.Build; 9 | 10 | import androidx.annotation.DrawableRes; 11 | import androidx.annotation.NonNull; 12 | import androidx.appcompat.widget.Toolbar; 13 | import androidx.core.content.ContextCompat; 14 | 15 | import org.alfonz.arch.R; 16 | 17 | public class ToolbarIndicator { 18 | public static final ToolbarIndicator NONE = new ToolbarIndicator(0, false, false); 19 | public static final ToolbarIndicator BACK = new ToolbarIndicator(0, true, true); 20 | public static final ToolbarIndicator CLOSE = new ToolbarIndicator(R.drawable.ic_close, true, true); 21 | 22 | @DrawableRes 23 | private final int mDrawableRes; 24 | private final boolean mIsHomeEnabled; 25 | private final boolean mIsHomeAsUpEnabled; 26 | 27 | public ToolbarIndicator(@DrawableRes int drawableRes, boolean isHomeEnabled, boolean isHomeAsUpEnabled) { 28 | mDrawableRes = drawableRes; 29 | mIsHomeEnabled = isHomeEnabled; 30 | mIsHomeAsUpEnabled = isHomeAsUpEnabled; 31 | } 32 | 33 | private static int getThemeTintColor(@NonNull Context context) { 34 | int attr; 35 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 36 | attr = android.R.attr.colorControlNormal; 37 | } else { 38 | attr = context.getResources().getIdentifier("colorControlNormal", "attr", context.getPackageName()); 39 | } 40 | 41 | return getColorValueOfAttribute(context, attr); 42 | } 43 | 44 | private static int getColorValueOfAttribute(@NonNull Context context, int attr) { 45 | TypedArray typedArray = context.obtainStyledAttributes(null, new int[]{attr}, 0, 0); 46 | int value = typedArray.getColor(0, 0); 47 | typedArray.recycle(); 48 | return value; 49 | } 50 | 51 | public Drawable getTintedDrawable(@NonNull Toolbar toolbar) { 52 | int color = getThemeTintColor(toolbar.getContext()); 53 | Drawable drawable = ContextCompat.getDrawable(toolbar.getContext(), mDrawableRes); 54 | drawable.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN)); 55 | return drawable; 56 | } 57 | 58 | public int getDrawableRes() { 59 | return mDrawableRes; 60 | } 61 | 62 | public boolean isHomeEnabled() { 63 | return mIsHomeEnabled; 64 | } 65 | 66 | public boolean isHomeAsUpEnabled() { 67 | return mIsHomeAsUpEnabled; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /alfonz-arch/src/main/res/drawable/ic_close.xml: -------------------------------------------------------------------------------- 1 | 7 | 10 | 11 | -------------------------------------------------------------------------------- /alfonz-arch/src/main/res/layout/binding_variables.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 9 | 12 | 15 | 16 | 17 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /alfonz-arch/src/main/res/values/ids.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /alfonz-graphics/README.md: -------------------------------------------------------------------------------- 1 | Alfonz - Graphics Module 2 | ======================== 3 | 4 | Utilities for working with bitmaps and drawables. 5 | 6 | 7 | How to use bitmap utilities 8 | --------------------------- 9 | 10 | `BitmapBlur` utility converts bitmap to blurred bitmap. 11 | 12 | ```java 13 | Bitmap originalBitmap = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.photo); 14 | Bitmap blurredBitmap = BitmapBlur.getBlurredBitmap(getContext(), originalBitmap); 15 | originalBitmap.recycle(); 16 | imageView.setImageBitmap(blurredBitmap); 17 | ``` 18 | 19 | `BitmapReflection` utility makes reflection effect. 20 | 21 | ```java 22 | Bitmap originalBitmap = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.photo); 23 | Bitmap reflectedBitmap = BitmapReflection.getReflectedBitmap(originalBitmap, 0); 24 | originalBitmap.recycle(); 25 | imageView.setImageBitmap(reflectedBitmap); 26 | ``` 27 | 28 | `BitmapScaler` utility is for resizing bitmaps. There are more variants for scaling. 29 | 30 | ```java 31 | Bitmap originalBitmap = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.photo); 32 | Bitmap scaledBitmap = BitmapScaler.scaleToFill(originalBitmap, 512, 512); 33 | originalBitmap.recycle(); 34 | imageView.setImageBitmap(scaledBitmap); 35 | ``` 36 | 37 | 38 | How to use drawables 39 | -------------------- 40 | 41 | `CircularDrawable` and `RoundedDrawable` are extended Drawables with circular/rounded shape. 42 | 43 | ```java 44 | CircularDrawable drawable = new CircularDrawable(bitmap); 45 | imageView.setImageDrawable(drawable); 46 | ``` 47 | 48 | ```java 49 | RoundedDrawable drawable = new RoundedDrawable(bitmap, radius); 50 | imageView.setImageDrawable(drawable); 51 | ``` 52 | 53 | `PlaceholderDrawable` is a drawable showing initial letter of passed string on a colorful background. 54 | 55 | ```java 56 | PlaceholderDrawable drawable = new PlaceholderDrawable(text, "?", 50, true); 57 | imageView.setImageDrawable(drawable); 58 | ``` 59 | 60 | 61 | Dependencies 62 | ------------ 63 | 64 | * AndroidX 65 | 66 | 67 | Samples and download 68 | -------------------- 69 | 70 | See the main [README](https://github.com/petrnohejl/Alfonz/) file. 71 | -------------------------------------------------------------------------------- /alfonz-graphics/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.library" 2 | apply from: "../utils.gradle" 3 | 4 | ext { 5 | bintrayName = "alfonz-graphics" 6 | libraryName = "Alfonz-Graphics" 7 | artifact = "alfonz-graphics" 8 | } 9 | 10 | android { 11 | compileSdkVersion 30 12 | buildToolsVersion "30.0.3" 13 | 14 | defaultConfig { 15 | minSdkVersion 19 16 | targetSdkVersion 30 17 | versionCode getVersionCode(majorVersion, minorVersion, patchVersion, buildVersion) 18 | versionName getVersionName(majorVersion, minorVersion, patchVersion) 19 | } 20 | 21 | buildTypes { 22 | release { 23 | minifyEnabled false 24 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 25 | } 26 | } 27 | 28 | compileOptions { 29 | sourceCompatibility JavaVersion.VERSION_1_7 30 | targetCompatibility JavaVersion.VERSION_1_7 31 | } 32 | } 33 | 34 | dependencies { 35 | implementation fileTree(dir: "libs", include: ["*.jar"]) 36 | implementation "androidx.annotation:annotation:$androidxAnnotationVersion" 37 | } 38 | 39 | apply from: "../install.gradle" 40 | apply from: "../bintray.gradle" 41 | -------------------------------------------------------------------------------- /alfonz-graphics/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /alfonz-graphics/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /alfonz-graphics/src/main/java/org/alfonz/graphics/bitmap/BitmapBlur.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.graphics.bitmap; 2 | 3 | import android.content.Context; 4 | import android.graphics.Bitmap; 5 | import android.renderscript.Allocation; 6 | import android.renderscript.Element; 7 | import android.renderscript.RenderScript; 8 | import android.renderscript.ScriptIntrinsicBlur; 9 | 10 | import androidx.annotation.NonNull; 11 | 12 | public final class BitmapBlur { 13 | private static final float BITMAP_SCALE = 0.4F; 14 | private static final float BLUR_RADIUS = 20F; 15 | 16 | private BitmapBlur() {} 17 | 18 | public static Bitmap getBlurredBitmap(@NonNull Context context, @NonNull Bitmap bitmap) { 19 | return getBlurredBitmap(context, bitmap, BITMAP_SCALE, BLUR_RADIUS); 20 | } 21 | 22 | public static Bitmap getBlurredBitmap(@NonNull Context context, @NonNull Bitmap bitmap, float scale, float radius) { 23 | int width = Math.round(bitmap.getWidth() * scale); 24 | int height = Math.round(bitmap.getHeight() * scale); 25 | 26 | Bitmap inputBitmap = Bitmap.createScaledBitmap(bitmap, width, height, false); 27 | Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap); 28 | 29 | RenderScript rs = RenderScript.create(context); 30 | ScriptIntrinsicBlur scriptIntrinsicBlur = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); 31 | Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap); 32 | Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap); 33 | scriptIntrinsicBlur.setRadius(radius); 34 | scriptIntrinsicBlur.setInput(tmpIn); 35 | scriptIntrinsicBlur.forEach(tmpOut); 36 | tmpOut.copyTo(outputBitmap); 37 | rs.destroy(); 38 | 39 | return outputBitmap; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /alfonz-graphics/src/main/java/org/alfonz/graphics/bitmap/BitmapScaler.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.graphics.bitmap; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | public final class BitmapScaler { 8 | private BitmapScaler() {} 9 | 10 | // scale and keep aspect ratio 11 | public static Bitmap scaleToFitWidth(@NonNull Bitmap bitmap, int width) { 12 | float factor = width / (float) bitmap.getWidth(); 13 | return Bitmap.createScaledBitmap(bitmap, width, (int) (bitmap.getHeight() * factor), true); 14 | } 15 | 16 | // scale and keep aspect ratio 17 | public static Bitmap scaleToFitHeight(@NonNull Bitmap bitmap, int height) { 18 | float factor = height / (float) bitmap.getHeight(); 19 | return Bitmap.createScaledBitmap(bitmap, (int) (bitmap.getWidth() * factor), height, true); 20 | } 21 | 22 | // scale and keep aspect ratio 23 | public static Bitmap scaleToFill(@NonNull Bitmap bitmap, int width, int height) { 24 | float factorH = height / (float) bitmap.getWidth(); 25 | float factorW = width / (float) bitmap.getWidth(); 26 | float factorToUse = Math.min(factorH, factorW); 27 | return Bitmap.createScaledBitmap(bitmap, (int) (bitmap.getWidth() * factorToUse), (int) (bitmap.getHeight() * factorToUse), true); 28 | } 29 | 30 | // scale and don't keep aspect ratio 31 | public static Bitmap stretchToFill(@NonNull Bitmap bitmap, int width, int height) { 32 | float factorH = height / (float) bitmap.getHeight(); 33 | float factorW = width / (float) bitmap.getWidth(); 34 | return Bitmap.createScaledBitmap(bitmap, (int) (bitmap.getWidth() * factorW), (int) (bitmap.getHeight() * factorH), true); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /alfonz-graphics/src/main/java/org/alfonz/graphics/drawable/RoundedDrawable.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.graphics.drawable; 2 | 3 | import android.graphics.Bitmap; 4 | import android.graphics.BitmapShader; 5 | import android.graphics.Canvas; 6 | import android.graphics.ColorFilter; 7 | import android.graphics.Paint; 8 | import android.graphics.PixelFormat; 9 | import android.graphics.Rect; 10 | import android.graphics.RectF; 11 | import android.graphics.Shader; 12 | import android.graphics.drawable.Drawable; 13 | 14 | import androidx.annotation.NonNull; 15 | 16 | public class RoundedDrawable extends Drawable { 17 | private Bitmap mBitmap; 18 | private float mCornerRadius; 19 | private int mMargin; 20 | private Paint mPaint; 21 | private RectF mRect = new RectF(); 22 | 23 | public RoundedDrawable(@NonNull Bitmap bitmap, float cornerRadius) { 24 | this(bitmap, cornerRadius, 0); 25 | } 26 | 27 | public RoundedDrawable(@NonNull Bitmap bitmap, float cornerRadius, int margin) { 28 | mBitmap = bitmap; 29 | mCornerRadius = cornerRadius; 30 | mMargin = margin; 31 | 32 | BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); 33 | 34 | mPaint = new Paint(); 35 | mPaint.setAntiAlias(true); 36 | mPaint.setShader(bitmapShader); 37 | } 38 | 39 | @Override 40 | protected void onBoundsChange(@NonNull Rect bounds) { 41 | super.onBoundsChange(bounds); 42 | mRect.set(mMargin, mMargin, bounds.width() - mMargin, bounds.height() - mMargin); 43 | } 44 | 45 | @Override 46 | public void draw(@NonNull Canvas canvas) { 47 | canvas.drawRoundRect(mRect, mCornerRadius, mCornerRadius, mPaint); 48 | } 49 | 50 | @Override 51 | public void setAlpha(int alpha) { 52 | mPaint.setAlpha(alpha); 53 | } 54 | 55 | @Override 56 | public void setColorFilter(ColorFilter colorFilter) { 57 | mPaint.setColorFilter(colorFilter); 58 | } 59 | 60 | @Override 61 | public int getOpacity() { 62 | return PixelFormat.TRANSLUCENT; 63 | } 64 | 65 | @Override 66 | public int getIntrinsicWidth() { 67 | return mBitmap.getWidth(); 68 | } 69 | 70 | @Override 71 | public int getIntrinsicHeight() { 72 | return mBitmap.getHeight(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /alfonz-media/README.md: -------------------------------------------------------------------------------- 1 | Alfonz - Media Module 2 | ===================== 3 | 4 | Utilities for working with images, sounds and videos. 5 | 6 | 7 | How to use ImagePicker 8 | ---------------------- 9 | 10 | Create a new instance of `ImagePicker`. Specify the name of the album directory. 11 | 12 | ```java 13 | private ImagePicker mImagePicker = new ImagePicker(getContext(), getString(R.string.app_name)); 14 | ``` 15 | 16 | Override `onActivityResult()` as follows. 17 | 18 | ```java 19 | @Override 20 | public void onActivityResult(int requestCode, int resultCode, Intent data) { 21 | mImagePicker.onActivityResult(this, requestCode, resultCode, data); 22 | } 23 | ``` 24 | 25 | Pick an image from camera or gallery when user clicks on a button. Note that it requires `READ_EXTERNAL_STORAGE` permission. 26 | 27 | ```java 28 | mImagePicker.pickImageFromCamera( 29 | this, 30 | (pickable, bitmap, path) -> pickable.handleImagePicked(bitmap, path), 31 | pickable -> pickable.handleImageCanceled()); 32 | ``` 33 | 34 | ```java 35 | mImagePicker.pickImageFromGallery( 36 | this, 37 | (pickable, bitmap, path) -> pickable.handleImagePicked(bitmap, path), 38 | pickable -> pickable.handleImageCanceled()); 39 | ``` 40 | 41 | Pickable variable in the lambda expression represents current instance of Fragment or Activity which has been passed in `onActivityResult()` method. 42 | 43 | 44 | How to use SoundManager 45 | ----------------------- 46 | 47 | Create a new instance of `SoundManager`. You can choose which playback mode you prefer to use. 48 | 49 | ```java 50 | private SoundManager mSoundManager = new SoundManager(getContext(), SoundManager.PLAY_SINGLE); 51 | ``` 52 | 53 | Play a sound from storage or assets. 54 | 55 | ```java 56 | mSoundManager.play(path); 57 | mSoundManager.playAsset(filename); 58 | ``` 59 | 60 | Stop all playing sounds and release resources in `Activity.onStop()`. 61 | 62 | ```java 63 | @Override 64 | public void onStop() { 65 | mSoundManager.stopAll(); 66 | } 67 | ``` 68 | 69 | 70 | Dependencies 71 | ------------ 72 | 73 | * Alfonz Graphics Module 74 | * AndroidX 75 | 76 | 77 | Samples and download 78 | -------------------- 79 | 80 | See the main [README](https://github.com/petrnohejl/Alfonz/) file. 81 | -------------------------------------------------------------------------------- /alfonz-media/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.library" 2 | apply from: "../utils.gradle" 3 | 4 | ext { 5 | bintrayName = "alfonz-media" 6 | libraryName = "Alfonz-Media" 7 | artifact = "alfonz-media" 8 | } 9 | 10 | android { 11 | compileSdkVersion 30 12 | buildToolsVersion "30.0.3" 13 | 14 | defaultConfig { 15 | minSdkVersion 19 16 | targetSdkVersion 30 17 | versionCode getVersionCode(majorVersion, minorVersion, patchVersion, buildVersion) 18 | versionName getVersionName(majorVersion, minorVersion, patchVersion) 19 | } 20 | 21 | buildTypes { 22 | release { 23 | minifyEnabled false 24 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 25 | } 26 | } 27 | 28 | compileOptions { 29 | sourceCompatibility JavaVersion.VERSION_1_7 30 | targetCompatibility JavaVersion.VERSION_1_7 31 | } 32 | } 33 | 34 | dependencies { 35 | implementation fileTree(dir: "libs", include: ["*.jar"]) 36 | implementation project(":alfonz-graphics") 37 | implementation "androidx.annotation:annotation:$androidxAnnotationVersion" 38 | implementation "androidx.exifinterface:exifinterface:$androidxExifInterfaceVersion" 39 | implementation "androidx.fragment:fragment:$androidxFragmentVersion" 40 | } 41 | 42 | apply from: "../install.gradle" 43 | apply from: "../bintray.gradle" 44 | -------------------------------------------------------------------------------- /alfonz-media/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /alfonz-media/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /alfonz-rest/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.library" 2 | apply from: "../utils.gradle" 3 | 4 | ext { 5 | bintrayName = "alfonz-rest" 6 | libraryName = "Alfonz-Rest" 7 | artifact = "alfonz-rest" 8 | } 9 | 10 | android { 11 | compileSdkVersion 30 12 | buildToolsVersion "30.0.3" 13 | 14 | defaultConfig { 15 | minSdkVersion 19 16 | targetSdkVersion 30 17 | versionCode getVersionCode(majorVersion, minorVersion, patchVersion, buildVersion) 18 | versionName getVersionName(majorVersion, minorVersion, patchVersion) 19 | } 20 | 21 | buildTypes { 22 | release { 23 | minifyEnabled false 24 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 25 | } 26 | } 27 | 28 | compileOptions { 29 | sourceCompatibility JavaVersion.VERSION_1_8 30 | targetCompatibility JavaVersion.VERSION_1_8 31 | } 32 | } 33 | 34 | dependencies { 35 | implementation fileTree(dir: "libs", include: ["*.jar"]) 36 | implementation project(":alfonz-rx") 37 | implementation "androidx.annotation:annotation:$androidxAnnotationVersion" 38 | implementation "androidx.collection:collection:$androidxCollectionVersion" 39 | implementation "com.squareup.okhttp3:okhttp:$okHttpVersion" 40 | implementation "com.squareup.retrofit2:retrofit:$retrofitVersion" 41 | implementation "io.reactivex.rxjava3:rxjava:$rxJavaVersion" 42 | } 43 | 44 | apply from: "../install.gradle" 45 | apply from: "../bintray.gradle" 46 | -------------------------------------------------------------------------------- /alfonz-rest/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /alfonz-rest/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /alfonz-rest/src/main/java/org/alfonz/rest/HttpException.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.rest; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | import retrofit2.Response; 6 | 7 | public abstract class HttpException extends retrofit2.HttpException { 8 | private final Object mError; 9 | 10 | public HttpException(@NonNull Response response) { 11 | super(response); 12 | mError = parseError(response); 13 | } 14 | 15 | public abstract Object parseError(@NonNull Response response); 16 | 17 | public Object error() { 18 | return mError; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /alfonz-rest/src/main/java/org/alfonz/rest/HttpLogger.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.rest; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | public interface HttpLogger { 6 | void logSuccess(@NonNull String message); 7 | void logError(@NonNull String message); 8 | void logFail(@NonNull String message); 9 | } 10 | -------------------------------------------------------------------------------- /alfonz-rest/src/main/java/org/alfonz/rest/ResponseHandler.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.rest; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | import retrofit2.Response; 6 | 7 | public interface ResponseHandler { 8 | boolean isSuccess(@NonNull Response response); 9 | String getErrorMessage(@NonNull HttpException exception); 10 | String getFailMessage(@NonNull Throwable throwable); 11 | HttpException createHttpException(@NonNull Response response); 12 | } 13 | -------------------------------------------------------------------------------- /alfonz-rest/src/main/java/org/alfonz/rest/call/BaseCallManager.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.rest.call; 2 | 3 | import android.util.Log; 4 | 5 | import androidx.annotation.NonNull; 6 | import androidx.collection.ArrayMap; 7 | 8 | import java.util.Map; 9 | 10 | import retrofit2.Call; 11 | import retrofit2.Callback; 12 | 13 | class BaseCallManager { 14 | private static final String TAG = "ALFONZ"; 15 | 16 | private Map> mCalls = new ArrayMap<>(); 17 | private Map mTypes = new ArrayMap<>(); 18 | 19 | public void enqueueCall(@NonNull Call call, @NonNull Callback callback, @NonNull String callType) { 20 | mCalls.put(callback.hashCode(), call); 21 | mTypes.put(callback.hashCode(), callType); 22 | call.enqueue(callback); 23 | } 24 | 25 | public void finishCall(@NonNull Callback callback) { 26 | mCalls.remove(callback.hashCode()); 27 | mTypes.remove(callback.hashCode()); 28 | } 29 | 30 | public Call getCall(@NonNull Callback callback) { 31 | return mCalls.get(callback.hashCode()); 32 | } 33 | 34 | public String getCallType(@NonNull Callback callback) { 35 | return mTypes.get(callback.hashCode()); 36 | } 37 | 38 | public int getCallsCount() { 39 | return mCalls.size(); 40 | } 41 | 42 | public boolean hasRunningCall(@NonNull String callType) { 43 | return mTypes.containsValue(callType); 44 | } 45 | 46 | public void cancelRunningCalls() { 47 | for (Call call : mCalls.values()) { 48 | if (call != null) { 49 | call.cancel(); 50 | } 51 | } 52 | mCalls.clear(); 53 | mTypes.clear(); 54 | } 55 | 56 | public void printRunningCalls() { 57 | String codeLocation = "[" + BaseCallManager.class.getSimpleName() + ".printRunningCalls] "; 58 | 59 | if (mCalls.isEmpty()) { 60 | Log.d(TAG, codeLocation + "empty"); 61 | return; 62 | } 63 | 64 | for (String callType : mTypes.values()) { 65 | Log.d(TAG, codeLocation + callType); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /alfonz-rest/src/main/java/org/alfonz/rest/call/CallManager.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.rest.call; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.annotation.Nullable; 5 | 6 | import org.alfonz.rest.HttpException; 7 | import org.alfonz.rest.HttpLogger; 8 | import org.alfonz.rest.ResponseHandler; 9 | 10 | public class CallManager extends BaseCallManager { 11 | private ResponseHandler mResponseHandler; 12 | private HttpLogger mHttpLogger; 13 | 14 | public CallManager(@NonNull ResponseHandler responseHandler) { 15 | mResponseHandler = responseHandler; 16 | } 17 | 18 | public CallManager(@NonNull ResponseHandler responseHandler, @Nullable HttpLogger httpLogger) { 19 | mResponseHandler = responseHandler; 20 | mHttpLogger = httpLogger; 21 | } 22 | 23 | public String getHttpErrorMessage(@NonNull Throwable throwable) { 24 | if (throwable instanceof HttpException) { 25 | return mResponseHandler.getErrorMessage((HttpException) throwable); 26 | } else { 27 | throwable.printStackTrace(); 28 | return mResponseHandler.getFailMessage(throwable); 29 | } 30 | } 31 | 32 | @NonNull 33 | ResponseHandler getResponseHandler() { 34 | return mResponseHandler; 35 | } 36 | 37 | @Nullable 38 | HttpLogger getHttpLogger() { 39 | return mHttpLogger; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /alfonz-rest/src/main/java/org/alfonz/rest/http/GzipRequestInterceptor.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.rest.http; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | import java.io.IOException; 6 | 7 | import okhttp3.Interceptor; 8 | import okhttp3.MediaType; 9 | import okhttp3.Request; 10 | import okhttp3.RequestBody; 11 | import okhttp3.Response; 12 | import okio.Buffer; 13 | import okio.BufferedSink; 14 | import okio.GzipSink; 15 | import okio.Okio; 16 | 17 | public class GzipRequestInterceptor implements Interceptor { 18 | @NonNull 19 | @Override 20 | public Response intercept(@NonNull Chain chain) throws IOException { 21 | Request originalRequest = chain.request(); 22 | 23 | if (originalRequest.body() == null || originalRequest.header("Content-Encoding") != null) { 24 | return chain.proceed(originalRequest); 25 | } 26 | 27 | Request compressedRequest = originalRequest.newBuilder() 28 | .header("Content-Encoding", "gzip") 29 | .method(originalRequest.method(), forceContentLength(gzip(originalRequest.body()))) 30 | .build(); 31 | 32 | return chain.proceed(compressedRequest); 33 | } 34 | 35 | private RequestBody gzip(@NonNull final RequestBody body) { 36 | return new RequestBody() { 37 | @Override 38 | public MediaType contentType() { 39 | return body.contentType(); 40 | } 41 | 42 | @Override 43 | public long contentLength() { 44 | // we don't know the compressed length in advance 45 | return -1; 46 | } 47 | 48 | @Override 49 | public void writeTo(@NonNull BufferedSink sink) throws IOException { 50 | BufferedSink gzipSink = Okio.buffer(new GzipSink(sink)); 51 | body.writeTo(gzipSink); 52 | gzipSink.close(); 53 | } 54 | }; 55 | } 56 | 57 | private RequestBody forceContentLength(@NonNull final RequestBody requestBody) throws IOException { 58 | final Buffer buffer = new Buffer(); 59 | requestBody.writeTo(buffer); 60 | return new RequestBody() { 61 | @Override 62 | public MediaType contentType() { 63 | return requestBody.contentType(); 64 | } 65 | 66 | @Override 67 | public long contentLength() { 68 | return buffer.size(); 69 | } 70 | 71 | @Override 72 | public void writeTo(@NonNull BufferedSink sink) throws IOException { 73 | sink.write(buffer.snapshot()); 74 | } 75 | }; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /alfonz-rx/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.library" 2 | apply from: "../utils.gradle" 3 | 4 | ext { 5 | bintrayName = "alfonz-rx" 6 | libraryName = "Alfonz-Rx" 7 | artifact = "alfonz-rx" 8 | } 9 | 10 | android { 11 | compileSdkVersion 30 12 | buildToolsVersion "30.0.3" 13 | 14 | defaultConfig { 15 | minSdkVersion 19 16 | targetSdkVersion 30 17 | versionCode getVersionCode(majorVersion, minorVersion, patchVersion, buildVersion) 18 | versionName getVersionName(majorVersion, minorVersion, patchVersion) 19 | } 20 | 21 | buildTypes { 22 | release { 23 | minifyEnabled false 24 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 25 | } 26 | } 27 | 28 | compileOptions { 29 | sourceCompatibility JavaVersion.VERSION_1_8 30 | targetCompatibility JavaVersion.VERSION_1_8 31 | } 32 | } 33 | 34 | dependencies { 35 | implementation fileTree(dir: "libs", include: ["*.jar"]) 36 | implementation "androidx.annotation:annotation:$androidxAnnotationVersion" 37 | implementation "androidx.collection:collection:$androidxCollectionVersion" 38 | implementation "com.jakewharton.rxrelay3:rxrelay:$rxRelayVersion" 39 | implementation "io.reactivex.rxjava3:rxandroid:$rxAndroidVersion" 40 | implementation "io.reactivex.rxjava3:rxjava:$rxJavaVersion" 41 | } 42 | 43 | apply from: "../install.gradle" 44 | apply from: "../bintray.gradle" 45 | -------------------------------------------------------------------------------- /alfonz-rx/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /alfonz-rx/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /alfonz-rx/src/main/java/org/alfonz/rx/AlfonzDisposableCompletableObserver.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.rx; 2 | 3 | import androidx.annotation.Nullable; 4 | 5 | import io.reactivex.rxjava3.annotations.NonNull; 6 | import io.reactivex.rxjava3.functions.Action; 7 | import io.reactivex.rxjava3.functions.Consumer; 8 | import io.reactivex.rxjava3.observers.DisposableCompletableObserver; 9 | 10 | public class AlfonzDisposableCompletableObserver extends DisposableCompletableObserver { 11 | @Nullable private Action mOnCompleteAction; 12 | @Nullable private Consumer mOnErrorAction; 13 | 14 | private AlfonzDisposableCompletableObserver(@Nullable Action onCompleteAction, @Nullable Consumer onErrorAction) { 15 | mOnCompleteAction = onCompleteAction; 16 | mOnErrorAction = onErrorAction; 17 | } 18 | 19 | public static AlfonzDisposableCompletableObserver newInstance() { 20 | return newInstance(null, null); 21 | } 22 | 23 | public static AlfonzDisposableCompletableObserver newInstance(@Nullable Action onCompleteAction) { 24 | return newInstance(onCompleteAction, null); 25 | } 26 | 27 | public static AlfonzDisposableCompletableObserver newInstance(@Nullable Action onCompleteAction, @Nullable Consumer onErrorAction) { 28 | return new AlfonzDisposableCompletableObserver(onCompleteAction, onErrorAction); 29 | } 30 | 31 | @Override 32 | public void onComplete() { 33 | if (mOnCompleteAction == null) return; 34 | try { 35 | mOnCompleteAction.run(); 36 | } catch (Throwable throwable) { 37 | throwable.printStackTrace(); 38 | } 39 | } 40 | 41 | @Override 42 | public void onError(@NonNull Throwable t) { 43 | if (mOnErrorAction == null) return; 44 | try { 45 | mOnErrorAction.accept(t); 46 | } catch (Throwable throwable) { 47 | throwable.printStackTrace(); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /alfonz-rx/src/main/java/org/alfonz/rx/AlfonzDisposableMaybeObserver.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.rx; 2 | 3 | import androidx.annotation.Nullable; 4 | 5 | import io.reactivex.rxjava3.annotations.NonNull; 6 | import io.reactivex.rxjava3.functions.Action; 7 | import io.reactivex.rxjava3.functions.Consumer; 8 | import io.reactivex.rxjava3.observers.DisposableMaybeObserver; 9 | 10 | public class AlfonzDisposableMaybeObserver extends DisposableMaybeObserver { 11 | @Nullable private Consumer mOnSuccessAction; 12 | @Nullable private Consumer mOnErrorAction; 13 | @Nullable private Action mOnCompleteAction; 14 | 15 | private AlfonzDisposableMaybeObserver(@Nullable Consumer onSuccessAction, @Nullable Consumer onErrorAction, @Nullable Action onCompleteAction) { 16 | mOnSuccessAction = onSuccessAction; 17 | mOnErrorAction = onErrorAction; 18 | mOnCompleteAction = onCompleteAction; 19 | } 20 | 21 | public static AlfonzDisposableMaybeObserver newInstance() { 22 | return newInstance(null, null, null); 23 | } 24 | 25 | public static AlfonzDisposableMaybeObserver newInstance(@Nullable Consumer onSuccessAction) { 26 | return newInstance(onSuccessAction, null, null); 27 | } 28 | 29 | public static AlfonzDisposableMaybeObserver newInstance(@Nullable Consumer onSuccessAction, @Nullable Consumer onErrorAction) { 30 | return newInstance(onSuccessAction, onErrorAction, null); 31 | } 32 | 33 | public static AlfonzDisposableMaybeObserver newInstance(@Nullable Consumer onSuccessAction, @Nullable Consumer onErrorAction, @Nullable Action onCompleteAction) { 34 | return new AlfonzDisposableMaybeObserver<>(onSuccessAction, onErrorAction, onCompleteAction); 35 | } 36 | 37 | @Override 38 | public void onSuccess(@NonNull T value) { 39 | if (mOnSuccessAction == null) return; 40 | try { 41 | mOnSuccessAction.accept(value); 42 | } catch (Throwable throwable) { 43 | throwable.printStackTrace(); 44 | } 45 | } 46 | 47 | @Override 48 | public void onError(@NonNull Throwable t) { 49 | if (mOnErrorAction == null) return; 50 | try { 51 | mOnErrorAction.accept(t); 52 | } catch (Throwable throwable) { 53 | throwable.printStackTrace(); 54 | } 55 | } 56 | 57 | @Override 58 | public void onComplete() { 59 | if (mOnCompleteAction == null) return; 60 | try { 61 | mOnCompleteAction.run(); 62 | } catch (Throwable throwable) { 63 | throwable.printStackTrace(); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /alfonz-rx/src/main/java/org/alfonz/rx/AlfonzDisposableObserver.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.rx; 2 | 3 | import androidx.annotation.Nullable; 4 | 5 | import io.reactivex.rxjava3.functions.Action; 6 | import io.reactivex.rxjava3.functions.Consumer; 7 | import io.reactivex.rxjava3.observers.DisposableObserver; 8 | 9 | public class AlfonzDisposableObserver extends DisposableObserver { 10 | @Nullable private Consumer mOnNextAction; 11 | @Nullable private Consumer mOnErrorAction; 12 | @Nullable private Action mOnCompleteAction; 13 | 14 | private AlfonzDisposableObserver(@Nullable Consumer onNextAction, @Nullable Consumer onErrorAction, @Nullable Action onCompleteAction) { 15 | mOnNextAction = onNextAction; 16 | mOnErrorAction = onErrorAction; 17 | mOnCompleteAction = onCompleteAction; 18 | } 19 | 20 | public static AlfonzDisposableObserver newInstance() { 21 | return newInstance(null, null, null); 22 | } 23 | 24 | public static AlfonzDisposableObserver newInstance(@Nullable Consumer onNextAction) { 25 | return newInstance(onNextAction, null, null); 26 | } 27 | 28 | public static AlfonzDisposableObserver newInstance(@Nullable Consumer onNextAction, @Nullable Consumer onErrorAction) { 29 | return newInstance(onNextAction, onErrorAction, null); 30 | } 31 | 32 | public static AlfonzDisposableObserver newInstance(@Nullable Consumer onNextAction, @Nullable Consumer onErrorAction, @Nullable Action onCompleteAction) { 33 | return new AlfonzDisposableObserver<>(onNextAction, onErrorAction, onCompleteAction); 34 | } 35 | 36 | @Override 37 | public void onNext(T value) { 38 | if (mOnNextAction == null) return; 39 | try { 40 | mOnNextAction.accept(value); 41 | } catch (Throwable throwable) { 42 | throwable.printStackTrace(); 43 | } 44 | } 45 | 46 | @Override 47 | public void onError(Throwable t) { 48 | if (mOnErrorAction == null) return; 49 | try { 50 | mOnErrorAction.accept(t); 51 | } catch (Throwable throwable) { 52 | throwable.printStackTrace(); 53 | } 54 | } 55 | 56 | @Override 57 | public void onComplete() { 58 | if (mOnCompleteAction == null) return; 59 | try { 60 | mOnCompleteAction.run(); 61 | } catch (Throwable throwable) { 62 | throwable.printStackTrace(); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /alfonz-rx/src/main/java/org/alfonz/rx/AlfonzDisposableSingleObserver.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.rx; 2 | 3 | import androidx.annotation.Nullable; 4 | 5 | import io.reactivex.rxjava3.annotations.NonNull; 6 | import io.reactivex.rxjava3.functions.Consumer; 7 | import io.reactivex.rxjava3.observers.DisposableSingleObserver; 8 | 9 | public class AlfonzDisposableSingleObserver extends DisposableSingleObserver { 10 | @Nullable private Consumer mOnSuccessAction; 11 | @Nullable private Consumer mOnErrorAction; 12 | 13 | private AlfonzDisposableSingleObserver(@Nullable Consumer onSuccessAction, @Nullable Consumer onErrorAction) { 14 | mOnSuccessAction = onSuccessAction; 15 | mOnErrorAction = onErrorAction; 16 | } 17 | 18 | public static AlfonzDisposableSingleObserver newInstance() { 19 | return newInstance(null, null); 20 | } 21 | 22 | public static AlfonzDisposableSingleObserver newInstance(@Nullable Consumer onSuccessAction) { 23 | return newInstance(onSuccessAction, null); 24 | } 25 | 26 | public static AlfonzDisposableSingleObserver newInstance(@Nullable Consumer onSuccessAction, @Nullable Consumer onErrorAction) { 27 | return new AlfonzDisposableSingleObserver<>(onSuccessAction, onErrorAction); 28 | } 29 | 30 | @Override 31 | public void onSuccess(@NonNull T value) { 32 | if (mOnSuccessAction == null) return; 33 | try { 34 | mOnSuccessAction.accept(value); 35 | } catch (Throwable throwable) { 36 | throwable.printStackTrace(); 37 | } 38 | } 39 | 40 | @Override 41 | public void onError(@NonNull Throwable t) { 42 | if (mOnErrorAction == null) return; 43 | try { 44 | mOnErrorAction.accept(t); 45 | } catch (Throwable throwable) { 46 | throwable.printStackTrace(); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /alfonz-rx/src/main/java/org/alfonz/rx/RxBus.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.rx; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | import com.jakewharton.rxrelay3.PublishRelay; 6 | import com.jakewharton.rxrelay3.Relay; 7 | 8 | import io.reactivex.rxjava3.core.Observable; 9 | 10 | public class RxBus { 11 | private static volatile RxBus sRxBus; 12 | 13 | private final Relay mBus = PublishRelay.create().toSerialized(); 14 | 15 | private RxBus() {} 16 | 17 | public static RxBus getInstance() { 18 | if (sRxBus == null) { 19 | synchronized (RxBus.class) { 20 | if (sRxBus == null) { 21 | sRxBus = new RxBus(); 22 | } 23 | } 24 | } 25 | return sRxBus; 26 | } 27 | 28 | public Observable onEvent(@NonNull Class eventClass) { 29 | return mBus.ofType(eventClass); 30 | } 31 | 32 | public void send(@NonNull final Object event) { 33 | mBus.accept(event); 34 | } 35 | 36 | @NonNull 37 | public Observable toObservable() { 38 | return mBus; 39 | } 40 | 41 | public boolean hasObservers() { 42 | return mBus.hasObservers(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /alfonz-utility/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.library" 2 | apply from: "../utils.gradle" 3 | 4 | ext { 5 | bintrayName = "alfonz-utility" 6 | libraryName = "Alfonz-Utility" 7 | artifact = "alfonz-utility" 8 | } 9 | 10 | android { 11 | compileSdkVersion 30 12 | buildToolsVersion "30.0.3" 13 | 14 | defaultConfig { 15 | minSdkVersion 19 16 | targetSdkVersion 30 17 | versionCode getVersionCode(majorVersion, minorVersion, patchVersion, buildVersion) 18 | versionName getVersionName(majorVersion, minorVersion, patchVersion) 19 | } 20 | 21 | buildTypes { 22 | release { 23 | minifyEnabled false 24 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 25 | } 26 | } 27 | 28 | compileOptions { 29 | sourceCompatibility JavaVersion.VERSION_1_7 30 | targetCompatibility JavaVersion.VERSION_1_7 31 | } 32 | } 33 | 34 | dependencies { 35 | implementation fileTree(dir: "libs", include: ["*.jar"]) 36 | implementation "androidx.annotation:annotation:$androidxAnnotationVersion" 37 | implementation "androidx.fragment:fragment:$androidxFragmentVersion" 38 | implementation "com.google.android.material:material:$materialVersion" 39 | } 40 | 41 | apply from: "../install.gradle" 42 | apply from: "../bintray.gradle" 43 | -------------------------------------------------------------------------------- /alfonz-utility/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /alfonz-utility/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /alfonz-utility/src/main/java/org/alfonz/utility/DateConvertor.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.utility; 2 | 3 | import java.text.ParseException; 4 | import java.text.SimpleDateFormat; 5 | import java.util.Calendar; 6 | import java.util.Date; 7 | import java.util.Locale; 8 | 9 | // date format: https://developer.android.com/reference/java/text/SimpleDateFormat.html 10 | public final class DateConvertor { 11 | private DateConvertor() {} 12 | 13 | public static String dateToString(Date date, String format) { 14 | String str = null; 15 | if (date != null) { 16 | SimpleDateFormat dateFormat = new SimpleDateFormat(format, Locale.US); 17 | str = dateFormat.format(date); 18 | } 19 | return str; 20 | } 21 | 22 | public static Date stringToDate(String str, String format) { 23 | Date date = null; 24 | if (str != null) { 25 | SimpleDateFormat dateFormat = new SimpleDateFormat(format, Locale.US); 26 | try { date = dateFormat.parse(str); } catch (ParseException e) { e.printStackTrace(); } 27 | } 28 | return date; 29 | } 30 | 31 | public static Calendar dateToCalendar(Date date) { 32 | Calendar calendar = Calendar.getInstance(); 33 | calendar.setTime(date); 34 | return calendar; 35 | } 36 | 37 | public static Date calendarToDate(Calendar calendar) { 38 | return calendar.getTime(); 39 | } 40 | 41 | public static Calendar stringToCalendar(String str, String format) { 42 | Date date = stringToDate(str, format); 43 | return dateToCalendar(date); 44 | } 45 | 46 | public static String calendarToString(Calendar calendar, String format) { 47 | Date date = calendarToDate(calendar); 48 | return dateToString(date, format); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /alfonz-utility/src/main/java/org/alfonz/utility/DimensionUtility.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.utility; 2 | 3 | import android.content.Context; 4 | import android.util.DisplayMetrics; 5 | import android.util.TypedValue; 6 | 7 | import androidx.annotation.NonNull; 8 | 9 | public final class DimensionUtility { 10 | private DimensionUtility() {} 11 | 12 | public static float dp2px(@NonNull final Context context, final float dp) { 13 | DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); 14 | return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, displayMetrics); 15 | } 16 | 17 | public static float sp2px(@NonNull final Context context, final float sp) { 18 | DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); 19 | return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, sp, displayMetrics); 20 | } 21 | 22 | public static float px2dp(@NonNull final Context context, final float px) { 23 | DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); 24 | return px / ((float) displayMetrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT); 25 | } 26 | 27 | public static float px2sp(@NonNull final Context context, final float px) { 28 | DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics(); 29 | return px / displayMetrics.scaledDensity; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /alfonz-utility/src/main/java/org/alfonz/utility/DownloadUtility.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.utility; 2 | 3 | import android.app.DownloadManager; 4 | import android.content.Context; 5 | import android.net.Uri; 6 | import android.os.Environment; 7 | 8 | import androidx.annotation.NonNull; 9 | 10 | // requires android.permission.WRITE_EXTERNAL_STORAGE 11 | public final class DownloadUtility { 12 | private DownloadUtility() {} 13 | 14 | public static void downloadFile(@NonNull Context context, @NonNull String url, @NonNull String fileName) { 15 | DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url)); 16 | 17 | // set download directory 18 | request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName); 19 | 20 | // when downloading music and videos they will be listed in the player 21 | request.allowScanningByMediaScanner(); 22 | 23 | // notify user when download is completed 24 | request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); 25 | 26 | // start download 27 | DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); 28 | manager.enqueue(request); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /alfonz-utility/src/main/java/org/alfonz/utility/HashUtility.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.utility; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | import java.nio.charset.StandardCharsets; 6 | import java.security.MessageDigest; 7 | import java.security.NoSuchAlgorithmException; 8 | import java.util.Formatter; 9 | 10 | public final class HashUtility { 11 | private HashUtility() {} 12 | 13 | public static String getMd5(@NonNull byte[] data) { 14 | try { 15 | MessageDigest md = MessageDigest.getInstance("MD5"); 16 | byte[] bytes = md.digest(data); 17 | StringBuilder stringBuilder = new StringBuilder(); 18 | for (byte b : bytes) { 19 | stringBuilder.append(Integer.toHexString((b & 0xFF) | 0x100).substring(1, 3)); 20 | } 21 | return stringBuilder.toString(); 22 | } catch (NoSuchAlgorithmException e) { 23 | e.printStackTrace(); 24 | } 25 | return null; 26 | } 27 | 28 | public static String getMd5(@NonNull String data) { 29 | return getMd5(data.getBytes(StandardCharsets.UTF_8)); 30 | } 31 | 32 | public static String getSha1(@NonNull byte[] data) { 33 | try { 34 | MessageDigest md = MessageDigest.getInstance("SHA-1"); 35 | md.reset(); 36 | md.update(data); 37 | return byteToHex(md.digest()); 38 | } catch (NoSuchAlgorithmException e) { 39 | e.printStackTrace(); 40 | } 41 | return null; 42 | } 43 | 44 | public static String getSha1(@NonNull String data) { 45 | return getSha1(data.getBytes(StandardCharsets.UTF_8)); 46 | } 47 | 48 | private static String byteToHex(@NonNull final byte[] hash) { 49 | Formatter formatter = new Formatter(); 50 | for (byte b : hash) { 51 | formatter.format("%02x", b); 52 | } 53 | String result = formatter.toString(); 54 | formatter.close(); 55 | return result; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /alfonz-utility/src/main/java/org/alfonz/utility/KeyboardUtility.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.utility; 2 | 3 | import android.content.Context; 4 | import android.view.View; 5 | import android.view.inputmethod.InputMethodManager; 6 | 7 | import androidx.annotation.NonNull; 8 | 9 | public final class KeyboardUtility { 10 | private KeyboardUtility() {} 11 | 12 | public static void showKeyboard(@NonNull View view) { 13 | view.requestFocus(); 14 | InputMethodManager inputMethodManager = (InputMethodManager) view.getContext().getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE); 15 | inputMethodManager.showSoftInput(view, 0); 16 | } 17 | 18 | public static void hideKeyboard(@NonNull View view) { 19 | InputMethodManager inputMethodManager = (InputMethodManager) view.getContext().getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE); 20 | inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /alfonz-utility/src/main/java/org/alfonz/utility/NetworkUtility.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.utility; 2 | 3 | import android.content.Context; 4 | import android.net.ConnectivityManager; 5 | import android.net.NetworkInfo; 6 | 7 | import androidx.annotation.NonNull; 8 | 9 | // requires android.permission.ACCESS_NETWORK_STATE 10 | public final class NetworkUtility { 11 | private NetworkUtility() {} 12 | 13 | public static boolean isOnline(@NonNull Context context) { 14 | ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 15 | NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); 16 | return (networkInfo != null && networkInfo.isAvailable() && networkInfo.isConnected()); 17 | } 18 | 19 | public static int getType(@NonNull Context context) { 20 | ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 21 | NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); 22 | 23 | if (networkInfo != null) { 24 | // returns ConnectivityManager.TYPE_WIFI, ConnectivityManager.TYPE_MOBILE etc. 25 | return networkInfo.getType(); 26 | } else { 27 | return -1; 28 | } 29 | } 30 | 31 | public static String getTypeName(@NonNull Context context) { 32 | ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 33 | NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); 34 | 35 | if (networkInfo != null) { 36 | return networkInfo.getTypeName(); 37 | } else { 38 | return null; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /alfonz-utility/src/main/java/org/alfonz/utility/ResourcesUtility.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.utility; 2 | 3 | import android.content.Context; 4 | import android.content.res.Resources; 5 | import android.content.res.TypedArray; 6 | import android.graphics.drawable.Drawable; 7 | import android.util.TypedValue; 8 | 9 | import androidx.annotation.NonNull; 10 | 11 | public final class ResourcesUtility { 12 | private ResourcesUtility() {} 13 | 14 | public static int getValueOfAttribute(@NonNull Context context, int attr) { 15 | TypedValue typedValue = new TypedValue(); 16 | Resources.Theme theme = context.getTheme(); 17 | theme.resolveAttribute(attr, typedValue, true); 18 | return typedValue.data; 19 | } 20 | 21 | public static int getColorValueOfAttribute(@NonNull Context context, int attr) { 22 | TypedArray typedArray = context.obtainStyledAttributes(null, new int[]{attr}, 0, 0); 23 | int value = typedArray.getColor(0, 0); 24 | typedArray.recycle(); 25 | return value; 26 | } 27 | 28 | public static float getDimensionValueOfAttribute(@NonNull Context context, int attr) { 29 | TypedArray typedArray = context.obtainStyledAttributes(null, new int[]{attr}, 0, 0); 30 | float value = typedArray.getDimension(0, 0); 31 | typedArray.recycle(); 32 | return value; 33 | } 34 | 35 | public static int getDimensionPixelSizeValueOfAttribute(@NonNull Context context, int attr) { 36 | TypedArray typedArray = context.obtainStyledAttributes(null, new int[]{attr}, 0, 0); 37 | int value = typedArray.getDimensionPixelSize(0, 0); 38 | typedArray.recycle(); 39 | return value; 40 | } 41 | 42 | public static Drawable getDrawableValueOfAttribute(@NonNull Context context, int attr) { 43 | TypedArray typedArray = context.obtainStyledAttributes(null, new int[]{attr}, 0, 0); 44 | Drawable value = typedArray.getDrawable(0); 45 | typedArray.recycle(); 46 | return value; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /alfonz-utility/src/main/java/org/alfonz/utility/ServiceUtility.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.utility; 2 | 3 | import android.app.ActivityManager; 4 | import android.app.ActivityManager.RunningServiceInfo; 5 | import android.content.Context; 6 | 7 | import androidx.annotation.NonNull; 8 | 9 | public final class ServiceUtility { 10 | private ServiceUtility() {} 11 | 12 | public static boolean isRunning(@NonNull Context context, @NonNull Class cls) { 13 | ActivityManager activityManager = (ActivityManager) context.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE); 14 | for (RunningServiceInfo service : activityManager.getRunningServices(Integer.MAX_VALUE)) { 15 | if (cls.getName().equals(service.service.getClassName())) { 16 | return true; 17 | } 18 | } 19 | return false; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /alfonz-utility/src/main/java/org/alfonz/utility/StringConvertor.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.utility; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | public final class StringConvertor { 6 | private StringConvertor() {} 7 | 8 | public static String capitalize(@NonNull String str) { 9 | char[] chars = str.toLowerCase().toCharArray(); 10 | boolean found = false; 11 | for (int i = 0; i < chars.length; i++) { 12 | if (!found && Character.isLetter(chars[i])) { 13 | chars[i] = Character.toUpperCase(chars[i]); 14 | found = true; 15 | } else if (Character.isWhitespace(chars[i]) || chars[i] == '.' || chars[i] == '\'') { 16 | found = false; 17 | } 18 | } 19 | return String.valueOf(chars); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /alfonz-utility/src/main/java/org/alfonz/utility/ValidationUtility.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.utility; 2 | 3 | import android.util.Patterns; 4 | 5 | import androidx.annotation.NonNull; 6 | import androidx.annotation.Nullable; 7 | 8 | import java.text.ParseException; 9 | import java.text.SimpleDateFormat; 10 | import java.util.Locale; 11 | 12 | public final class ValidationUtility { 13 | private ValidationUtility() {} 14 | 15 | public static boolean isEmailValid(@Nullable CharSequence email) { 16 | return email != null && Patterns.EMAIL_ADDRESS.matcher(email).matches(); 17 | } 18 | 19 | public static boolean isDateValid(@Nullable String date, @NonNull String format) { 20 | if (date == null) { 21 | return false; 22 | } 23 | 24 | SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format, Locale.US); 25 | simpleDateFormat.setLenient(false); 26 | 27 | try { 28 | simpleDateFormat.parse(date); 29 | } catch (ParseException e) { 30 | e.printStackTrace(); 31 | return false; 32 | } 33 | 34 | return true; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /alfonz-utility/src/main/java/org/alfonz/utility/ZipUtility.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.utility; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | import java.io.BufferedInputStream; 6 | import java.io.File; 7 | import java.io.FileInputStream; 8 | import java.io.FileOutputStream; 9 | import java.io.IOException; 10 | import java.io.InputStream; 11 | import java.util.zip.ZipEntry; 12 | import java.util.zip.ZipInputStream; 13 | 14 | // requires android.permission.WRITE_EXTERNAL_STORAGE 15 | public final class ZipUtility { 16 | private ZipUtility() {} 17 | 18 | public static boolean unpackZip(@NonNull String path, @NonNull String zipname) { 19 | InputStream inputStream; 20 | ZipInputStream zipInputStream; 21 | 22 | try { 23 | int count; 24 | String filename; 25 | ZipEntry zipEntry; 26 | byte[] buffer = new byte[1024]; 27 | 28 | inputStream = new FileInputStream(path + zipname); 29 | zipInputStream = new ZipInputStream(new BufferedInputStream(inputStream)); 30 | 31 | while ((zipEntry = zipInputStream.getNextEntry()) != null) { 32 | filename = zipEntry.getName(); 33 | 34 | if (zipEntry.isDirectory()) { 35 | File f = new File(path + filename); 36 | f.mkdirs(); 37 | continue; 38 | } 39 | 40 | FileOutputStream fileOutputStream = new FileOutputStream(path + filename); 41 | 42 | while ((count = zipInputStream.read(buffer)) != -1) { 43 | fileOutputStream.write(buffer, 0, count); 44 | } 45 | 46 | fileOutputStream.close(); 47 | zipInputStream.closeEntry(); 48 | } 49 | 50 | zipInputStream.close(); 51 | } catch (IOException e) { 52 | e.printStackTrace(); 53 | return false; 54 | } 55 | 56 | return true; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /alfonz-view/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.library" 2 | apply from: "../utils.gradle" 3 | 4 | ext { 5 | bintrayName = "alfonz-view" 6 | libraryName = "Alfonz-View" 7 | artifact = "alfonz-view" 8 | } 9 | 10 | android { 11 | compileSdkVersion 30 12 | buildToolsVersion "30.0.3" 13 | 14 | defaultConfig { 15 | minSdkVersion 19 16 | targetSdkVersion 30 17 | versionCode getVersionCode(majorVersion, minorVersion, patchVersion, buildVersion) 18 | versionName getVersionName(majorVersion, minorVersion, patchVersion) 19 | } 20 | 21 | buildTypes { 22 | release { 23 | minifyEnabled false 24 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 25 | } 26 | } 27 | 28 | compileOptions { 29 | sourceCompatibility JavaVersion.VERSION_1_7 30 | targetCompatibility JavaVersion.VERSION_1_7 31 | } 32 | } 33 | 34 | dependencies { 35 | implementation fileTree(dir: "libs", include: ["*.jar"]) 36 | implementation "androidx.annotation:annotation:$androidxAnnotationVersion" 37 | implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion" 38 | } 39 | 40 | apply from: "../install.gradle" 41 | apply from: "../bintray.gradle" 42 | -------------------------------------------------------------------------------- /alfonz-view/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /alfonz-view/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /alfonz-view/src/main/java/org/alfonz/view/AspectRatioImageView.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.view; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import androidx.annotation.NonNull; 7 | import androidx.appcompat.widget.AppCompatImageView; 8 | 9 | public class AspectRatioImageView extends AppCompatImageView { 10 | public AspectRatioImageView(@NonNull Context context) { 11 | super(context); 12 | } 13 | 14 | public AspectRatioImageView(@NonNull Context context, AttributeSet attrs) { 15 | super(context, attrs); 16 | } 17 | 18 | public AspectRatioImageView(@NonNull Context context, AttributeSet attrs, int defStyle) { 19 | super(context, attrs, defStyle); 20 | } 21 | 22 | @Override 23 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 24 | int width = MeasureSpec.getSize(widthMeasureSpec); 25 | int height = 0; 26 | 27 | try { 28 | if (getDrawable() != null) { 29 | height = width * getDrawable().getIntrinsicHeight() / getDrawable().getIntrinsicWidth(); 30 | } 31 | } catch (ArithmeticException e) { 32 | e.printStackTrace(); 33 | } 34 | 35 | setMeasuredDimension(width, height); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /alfonz-view/src/main/java/org/alfonz/view/MaxWidthLinearLayout.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.view; 2 | 3 | import android.content.Context; 4 | import android.content.res.TypedArray; 5 | import android.util.AttributeSet; 6 | import android.widget.LinearLayout; 7 | 8 | import androidx.annotation.NonNull; 9 | 10 | // source: http://stackoverflow.com/questions/5875877/setting-a-maximum-width-on-a-viewgroup 11 | public class MaxWidthLinearLayout extends LinearLayout { 12 | private int mMaxWidth; 13 | 14 | public MaxWidthLinearLayout(@NonNull Context context) { 15 | super(context); 16 | mMaxWidth = 0; 17 | } 18 | 19 | public MaxWidthLinearLayout(@NonNull Context context, AttributeSet attrs) { 20 | super(context, attrs); 21 | TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.MaxWidthLinearLayout); 22 | mMaxWidth = typedArray.getDimensionPixelSize(R.styleable.MaxWidthLinearLayout_maxWidth, Integer.MAX_VALUE); 23 | typedArray.recycle(); 24 | } 25 | 26 | @Override 27 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 28 | int measuredWidth = MeasureSpec.getSize(widthMeasureSpec); 29 | if (mMaxWidth > 0 && mMaxWidth < measuredWidth) { 30 | int measureMode = MeasureSpec.getMode(widthMeasureSpec); 31 | widthMeasureSpec = MeasureSpec.makeMeasureSpec(mMaxWidth, measureMode); 32 | } 33 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /alfonz-view/src/main/java/org/alfonz/view/ObservableScrollView.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.view; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.widget.ScrollView; 6 | 7 | import androidx.annotation.NonNull; 8 | 9 | // source: http://stackoverflow.com/questions/3948934/synchronise-scrollview-scroll-positions-android 10 | public class ObservableScrollView extends ScrollView { 11 | private OnScrollViewListener mOnScrollViewListener = null; 12 | 13 | public interface OnScrollViewListener { 14 | void onScrollChanged(@NonNull ObservableScrollView scrollView, int x, int y, int oldx, int oldy); 15 | } 16 | 17 | public ObservableScrollView(@NonNull Context context) { 18 | super(context); 19 | } 20 | 21 | public ObservableScrollView(@NonNull Context context, AttributeSet attrs) { 22 | super(context, attrs); 23 | } 24 | 25 | public ObservableScrollView(@NonNull Context context, AttributeSet attrs, int defStyle) { 26 | super(context, attrs, defStyle); 27 | } 28 | 29 | @Override 30 | protected void onScrollChanged(int x, int y, int oldx, int oldy) { 31 | super.onScrollChanged(x, y, oldx, oldy); 32 | if (mOnScrollViewListener != null) { 33 | mOnScrollViewListener.onScrollChanged(this, x, y, oldx, oldy); 34 | } 35 | } 36 | 37 | public void setOnScrollViewListener(@NonNull OnScrollViewListener onScrollViewListener) { 38 | mOnScrollViewListener = onScrollViewListener; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /alfonz-view/src/main/java/org/alfonz/view/RotatableImageView.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.view; 2 | 3 | import android.content.Context; 4 | import android.content.res.TypedArray; 5 | import android.graphics.Canvas; 6 | import android.util.AttributeSet; 7 | 8 | import androidx.annotation.NonNull; 9 | import androidx.appcompat.widget.AppCompatImageView; 10 | 11 | public class RotatableImageView extends AppCompatImageView { 12 | private int mAngle; 13 | 14 | public RotatableImageView(Context context) { 15 | super(context); 16 | } 17 | 18 | public RotatableImageView(@NonNull Context context, AttributeSet attrs) { 19 | super(context, attrs); 20 | loadAttributes(context, attrs); 21 | } 22 | 23 | public RotatableImageView(@NonNull Context context, AttributeSet attrs, int defStyle) { 24 | super(context, attrs, defStyle); 25 | loadAttributes(context, attrs); 26 | } 27 | 28 | @Override 29 | protected void onDraw(Canvas canvas) // if you want to rotate the entire view (along with its background), you should override draw() instead of onDraw() 30 | { 31 | canvas.save(); 32 | canvas.rotate(mAngle % 360, getWidth() / 2F, getHeight() / 2F); 33 | super.onDraw(canvas); 34 | canvas.restore(); 35 | 36 | // Drawable drawable = getDrawable(); 37 | // Bitmap bitmap = ((BitmapDrawable)drawable).getBitmap(); 38 | // 39 | // Matrix transform = new Matrix(); 40 | // transform.preRotate(mAngle%360, canvas.getWidth()/2, canvas.getHeight()/2); 41 | // 42 | // canvas.save(); 43 | // canvas.drawBitmap(bitmap, transform, null); 44 | // canvas.restore(); 45 | } 46 | 47 | @Override 48 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 49 | int w = getDrawable().getIntrinsicWidth(); 50 | int h = getDrawable().getIntrinsicHeight(); 51 | double a = Math.toRadians(mAngle); 52 | 53 | int width = (int) (Math.abs(w * Math.cos(a)) + Math.abs(h * Math.sin(a))); 54 | int height = (int) (Math.abs(w * Math.sin(a)) + Math.abs(h * Math.cos(a))); 55 | 56 | setMeasuredDimension(width, height); 57 | } 58 | 59 | public int getAngle() { 60 | return mAngle; 61 | } 62 | 63 | public void setAngle(int angle) { 64 | mAngle = angle; 65 | } 66 | 67 | private void loadAttributes(Context context, AttributeSet attrs) { 68 | TypedArray arr = context.obtainStyledAttributes(attrs, R.styleable.RotatableImageView); 69 | mAngle = arr.getInteger(R.styleable.RotatableImageView_angle, 0); 70 | arr.recycle(); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /alfonz-view/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /bintray.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.jfrog.bintray' 2 | 3 | version = libraryVersion 4 | 5 | if (project.hasProperty("android")) { // Android libraries 6 | task sourcesJar(type: Jar) { 7 | classifier = 'sources' 8 | from android.sourceSets.main.java.srcDirs 9 | } 10 | 11 | task javadoc(type: Javadoc) { 12 | source = android.sourceSets.main.java.srcDirs 13 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) 14 | } 15 | } else { // Java libraries 16 | task sourcesJar(type: Jar, dependsOn: classes) { 17 | classifier = 'sources' 18 | from sourceSets.main.allSource 19 | } 20 | } 21 | 22 | task javadocJar(type: Jar, dependsOn: javadoc) { 23 | classifier = 'javadoc' 24 | from javadoc.destinationDir 25 | } 26 | 27 | artifacts { 28 | archives javadocJar 29 | archives sourcesJar 30 | } 31 | 32 | // Bintray 33 | Properties properties = new Properties() 34 | properties.load(project.rootProject.file('local.properties').newDataInputStream()) 35 | 36 | bintray { 37 | user = properties.getProperty("bintray.user") 38 | key = properties.getProperty("bintray.apikey") 39 | 40 | configurations = ['archives'] 41 | pkg { 42 | repo = bintrayRepo 43 | name = bintrayName 44 | userOrg = properties.getProperty("bintray.org") 45 | desc = libraryDescription 46 | websiteUrl = siteUrl 47 | vcsUrl = gitUrl 48 | licenses = allLicenses 49 | publish = true 50 | publicDownloadNumbers = true 51 | version { 52 | desc = libraryDescription 53 | // gpg { 54 | // sign = true //Determines whether to GPG sign the files. The default is false 55 | // passphrase = properties.getProperty("bintray.gpg.password") //Optional. The passphrase for GPG signing' 56 | // } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /extras/graphics/alfonz.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petrnohejl/alfonz/ed7e04b2dcb3476a4a085690dd0b618b91c61b4b/extras/graphics/alfonz.gif -------------------------------------------------------------------------------- /extras/graphics/avatar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petrnohejl/alfonz/ed7e04b2dcb3476a4a085690dd0b618b91c61b4b/extras/graphics/avatar.gif -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | 19 | android.useAndroidX=true 20 | android.enableJetifier=true 21 | android.databinding.incremental=true 22 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petrnohejl/alfonz/ed7e04b2dcb3476a4a085690dd0b618b91c61b4b/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Mar 26 15:11:25 CET 2021 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip 7 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /install.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.github.dcendents.android-maven' 2 | 3 | group = publishedGroupId // Maven Group ID for the artifact 4 | 5 | install { 6 | repositories.mavenInstaller { 7 | // This generates POM.xml with proper parameters 8 | pom { 9 | project { 10 | packaging 'aar' 11 | groupId publishedGroupId 12 | artifactId artifact 13 | 14 | // Add your description here 15 | name libraryName 16 | description libraryDescription 17 | url siteUrl 18 | 19 | // Set your license 20 | licenses { 21 | license { 22 | name licenseName 23 | url licenseUrl 24 | } 25 | } 26 | developers { 27 | developer { 28 | id developerId 29 | name developerName 30 | email developerEmail 31 | } 32 | } 33 | scm { 34 | connection gitUrl 35 | developerConnection gitUrl 36 | url siteUrl 37 | } 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /samples/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in C:\Android\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /samples/src/main/assets/sound.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petrnohejl/alfonz/ed7e04b2dcb3476a4a085690dd0b618b91c61b4b/samples/src/main/assets/sound.mp3 -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/SamplesActivity.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples; 2 | 3 | import android.os.Bundle; 4 | import android.widget.Button; 5 | 6 | import androidx.appcompat.app.AppCompatActivity; 7 | 8 | import org.alfonz.samples.alfonzadapter.AdapterSampleActivity; 9 | import org.alfonz.samples.alfonzarch.ArchSampleActivity; 10 | import org.alfonz.samples.alfonzgraphics.GraphicsSampleActivity; 11 | import org.alfonz.samples.alfonzmedia.MediaSampleActivity; 12 | import org.alfonz.samples.alfonzrest.RestSampleActivity; 13 | import org.alfonz.samples.alfonzrx.RxSampleActivity; 14 | import org.alfonz.samples.alfonzutility.UtilitySampleActivity; 15 | import org.alfonz.samples.alfonzview.ViewSampleActivity; 16 | 17 | public class SamplesActivity extends AppCompatActivity { 18 | @Override 19 | public void onCreate(Bundle savedInstanceState) { 20 | super.onCreate(savedInstanceState); 21 | setContentView(R.layout.activity_samples); 22 | setupButtons(); 23 | } 24 | 25 | private void setupButtons() { 26 | Button adapterButton = findViewById(R.id.samples_adapter); 27 | Button archButton = findViewById(R.id.samples_arch); 28 | Button graphicsButton = findViewById(R.id.samples_graphics); 29 | Button mediaButton = findViewById(R.id.samples_media); 30 | Button restButton = findViewById(R.id.samples_rest); 31 | Button rxButton = findViewById(R.id.samples_rx); 32 | Button utilityButton = findViewById(R.id.samples_utility); 33 | Button viewButton = findViewById(R.id.samples_view); 34 | 35 | adapterButton.setOnClickListener(view -> startActivity(AdapterSampleActivity.newIntent(SamplesActivity.this))); 36 | archButton.setOnClickListener(view -> startActivity(ArchSampleActivity.newIntent(SamplesActivity.this))); 37 | graphicsButton.setOnClickListener(view -> startActivity(GraphicsSampleActivity.newIntent(SamplesActivity.this))); 38 | mediaButton.setOnClickListener(view -> startActivity(MediaSampleActivity.newIntent(SamplesActivity.this))); 39 | restButton.setOnClickListener(view -> startActivity(RestSampleActivity.newIntent(SamplesActivity.this))); 40 | rxButton.setOnClickListener(view -> startActivity(RxSampleActivity.newIntent(SamplesActivity.this))); 41 | utilityButton.setOnClickListener(view -> startActivity(UtilitySampleActivity.newIntent(SamplesActivity.this))); 42 | viewButton.setOnClickListener(view -> startActivity(ViewSampleActivity.newIntent(SamplesActivity.this))); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/SamplesApplication.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples; 2 | 3 | import android.app.Application; 4 | import android.content.Context; 5 | 6 | import org.alfonz.utility.Logcat; 7 | 8 | public class SamplesApplication extends Application { 9 | private static SamplesApplication sInstance; 10 | 11 | public SamplesApplication() { 12 | sInstance = this; 13 | } 14 | 15 | public static Context getContext() { 16 | return sInstance; 17 | } 18 | 19 | @Override 20 | public void onCreate() { 21 | super.onCreate(); 22 | 23 | // init logcat 24 | Logcat.init(SamplesConfig.LOGS, "ALFONZ"); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/SamplesConfig.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples; 2 | 3 | public class SamplesConfig { 4 | public static final boolean LOGS = BuildConfig.LOGS; 5 | public static final boolean DEV_ENVIRONMENT = BuildConfig.DEV_ENVIRONMENT; 6 | 7 | public static final String REST_BASE_URL_PROD = "https://api.github.com/"; 8 | public static final String REST_BASE_URL_DEV = "https://api.github.com/"; 9 | public static final String REST_BASE_URL = SamplesConfig.DEV_ENVIRONMENT ? SamplesConfig.REST_BASE_URL_DEV : SamplesConfig.REST_BASE_URL_PROD; 10 | } 11 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzadapter/AdapterSampleGridSimpleFragment.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzadapter; 2 | 3 | import android.os.Bundle; 4 | import android.view.LayoutInflater; 5 | 6 | import androidx.annotation.NonNull; 7 | import androidx.lifecycle.ViewModelProvider; 8 | 9 | import org.alfonz.samples.R; 10 | import org.alfonz.samples.alfonzarch.BaseFragment; 11 | import org.alfonz.samples.databinding.FragmentAdapterSampleGridBinding; 12 | 13 | public class AdapterSampleGridSimpleFragment extends BaseFragment implements AdapterSampleView { 14 | private MessageListSimpleAdapter mAdapter; 15 | 16 | public static AdapterSampleGridSimpleFragment newInstance() { 17 | return new AdapterSampleGridSimpleFragment(); 18 | } 19 | 20 | @Override 21 | public AdapterSampleViewModel setupViewModel() { 22 | AdapterSampleViewModel viewModel = new ViewModelProvider(this).get(AdapterSampleViewModel.class); 23 | getLifecycle().addObserver(viewModel); 24 | return viewModel; 25 | } 26 | 27 | @Override 28 | public FragmentAdapterSampleGridBinding inflateBindingLayout(@NonNull LayoutInflater inflater) { 29 | return FragmentAdapterSampleGridBinding.inflate(inflater); 30 | } 31 | 32 | @Override 33 | public void onActivityCreated(Bundle savedInstanceState) { 34 | super.onActivityCreated(savedInstanceState); 35 | getBinding().executePendingBindings(); // helps to reload recycler scroll position after orientation change 36 | setupAdapter(); 37 | } 38 | 39 | @Override 40 | public void onItemClick(String message) { 41 | String newMessage = getViewModel().addMessage(); 42 | showSnackbar(getString(R.string.adapter_sample_hello, newMessage)); 43 | } 44 | 45 | @Override 46 | public boolean onItemLongClick(String message) { 47 | getViewModel().removeMessage(message); 48 | showToast(getString(R.string.adapter_sample_goodbye, message)); 49 | return true; 50 | } 51 | 52 | private void setupAdapter() { 53 | if (mAdapter == null) { 54 | mAdapter = new MessageListSimpleAdapter(this, getViewModel()); 55 | getBinding().adapterSampleGridRecycler.setAdapter(mAdapter); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzadapter/AdapterSampleListDiffFragment.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzadapter; 2 | 3 | import android.os.Bundle; 4 | import android.view.LayoutInflater; 5 | 6 | import androidx.annotation.NonNull; 7 | import androidx.lifecycle.ViewModelProvider; 8 | 9 | import org.alfonz.samples.R; 10 | import org.alfonz.samples.alfonzarch.BaseFragment; 11 | import org.alfonz.samples.databinding.FragmentAdapterSampleListDiffBinding; 12 | 13 | public class AdapterSampleListDiffFragment extends BaseFragment implements AdapterSampleView { 14 | private MessageListDiffAdapter mAdapter; 15 | 16 | public static AdapterSampleListDiffFragment newInstance() { 17 | return new AdapterSampleListDiffFragment(); 18 | } 19 | 20 | @Override 21 | public AdapterSampleDiffViewModel setupViewModel() { 22 | AdapterSampleDiffViewModel viewModel = new ViewModelProvider(this).get(AdapterSampleDiffViewModel.class); 23 | getLifecycle().addObserver(viewModel); 24 | return viewModel; 25 | } 26 | 27 | @Override 28 | public FragmentAdapterSampleListDiffBinding inflateBindingLayout(@NonNull LayoutInflater inflater) { 29 | return FragmentAdapterSampleListDiffBinding.inflate(inflater); 30 | } 31 | 32 | @Override 33 | public void onActivityCreated(Bundle savedInstanceState) { 34 | super.onActivityCreated(savedInstanceState); 35 | getBinding().executePendingBindings(); // helps to reload recycler scroll position after orientation change 36 | setupAdapter(); 37 | } 38 | 39 | @Override 40 | public void onItemClick(String message) { 41 | String newMessage = getViewModel().addMessage(); 42 | showSnackbar(getString(R.string.adapter_sample_hello, newMessage)); 43 | } 44 | 45 | @Override 46 | public boolean onItemLongClick(String message) { 47 | getViewModel().removeMessage(message); 48 | showToast(getString(R.string.adapter_sample_goodbye, message)); 49 | return true; 50 | } 51 | 52 | private void setupAdapter() { 53 | if (mAdapter == null) { 54 | mAdapter = new MessageListDiffAdapter(this); 55 | getBinding().adapterSampleListDiffRecycler.setAdapter(mAdapter); 56 | getViewModel().items.observe(getViewLifecycleOwner(), mAdapter::submitList); 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzadapter/AdapterSampleListMultiFragment.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzadapter; 2 | 3 | import android.os.Bundle; 4 | import android.view.LayoutInflater; 5 | 6 | import androidx.annotation.NonNull; 7 | import androidx.lifecycle.ViewModelProvider; 8 | 9 | import org.alfonz.samples.R; 10 | import org.alfonz.samples.alfonzarch.BaseFragment; 11 | import org.alfonz.samples.databinding.FragmentAdapterSampleListBinding; 12 | 13 | public class AdapterSampleListMultiFragment extends BaseFragment implements AdapterSampleView { 14 | private MessageListMultiAdapter mAdapter; 15 | 16 | public static AdapterSampleListMultiFragment newInstance() { 17 | return new AdapterSampleListMultiFragment(); 18 | } 19 | 20 | @Override 21 | public AdapterSampleViewModel setupViewModel() { 22 | AdapterSampleViewModel viewModel = new ViewModelProvider(this).get(AdapterSampleViewModel.class); 23 | getLifecycle().addObserver(viewModel); 24 | return viewModel; 25 | } 26 | 27 | @Override 28 | public FragmentAdapterSampleListBinding inflateBindingLayout(@NonNull LayoutInflater inflater) { 29 | return FragmentAdapterSampleListBinding.inflate(inflater); 30 | } 31 | 32 | @Override 33 | public void onActivityCreated(Bundle savedInstanceState) { 34 | super.onActivityCreated(savedInstanceState); 35 | getBinding().executePendingBindings(); // helps to reload recycler scroll position after orientation change 36 | setupAdapter(); 37 | } 38 | 39 | @Override 40 | public void onItemClick(String message) { 41 | String newMessage = getViewModel().addMessage(); 42 | showSnackbar(getString(R.string.adapter_sample_hello, newMessage)); 43 | } 44 | 45 | @Override 46 | public boolean onItemLongClick(String message) { 47 | getViewModel().removeMessage(message); 48 | showToast(getString(R.string.adapter_sample_goodbye, message)); 49 | return true; 50 | } 51 | 52 | private void setupAdapter() { 53 | if (mAdapter == null) { 54 | mAdapter = new MessageListMultiAdapter(this, getViewModel()); 55 | getBinding().adapterSampleListRecycler.setAdapter(mAdapter); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzadapter/AdapterSampleListSimpleFragment.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzadapter; 2 | 3 | import android.os.Bundle; 4 | import android.view.LayoutInflater; 5 | 6 | import androidx.annotation.NonNull; 7 | import androidx.lifecycle.ViewModelProvider; 8 | 9 | import org.alfonz.samples.R; 10 | import org.alfonz.samples.alfonzarch.BaseFragment; 11 | import org.alfonz.samples.databinding.FragmentAdapterSampleListBinding; 12 | 13 | public class AdapterSampleListSimpleFragment extends BaseFragment implements AdapterSampleView { 14 | private MessageListSimpleAdapter mAdapter; 15 | 16 | public static AdapterSampleListSimpleFragment newInstance() { 17 | return new AdapterSampleListSimpleFragment(); 18 | } 19 | 20 | @Override 21 | public AdapterSampleViewModel setupViewModel() { 22 | AdapterSampleViewModel viewModel = new ViewModelProvider(this).get(AdapterSampleViewModel.class); 23 | getLifecycle().addObserver(viewModel); 24 | return viewModel; 25 | } 26 | 27 | @Override 28 | public FragmentAdapterSampleListBinding inflateBindingLayout(@NonNull LayoutInflater inflater) { 29 | return FragmentAdapterSampleListBinding.inflate(inflater); 30 | } 31 | 32 | @Override 33 | public void onActivityCreated(Bundle savedInstanceState) { 34 | super.onActivityCreated(savedInstanceState); 35 | getBinding().executePendingBindings(); // helps to reload recycler scroll position after orientation change 36 | setupAdapter(); 37 | } 38 | 39 | @Override 40 | public void onItemClick(String message) { 41 | String newMessage = getViewModel().addMessage(); 42 | showSnackbar(getString(R.string.adapter_sample_hello, newMessage)); 43 | } 44 | 45 | @Override 46 | public boolean onItemLongClick(String message) { 47 | getViewModel().removeMessage(message); 48 | showToast(getString(R.string.adapter_sample_goodbye, message)); 49 | return true; 50 | } 51 | 52 | private void setupAdapter() { 53 | if (mAdapter == null) { 54 | mAdapter = new MessageListSimpleAdapter(this, getViewModel()); 55 | getBinding().adapterSampleListRecycler.setAdapter(mAdapter); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzadapter/AdapterSamplePagerMultiFragment.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzadapter; 2 | 3 | import android.os.Bundle; 4 | import android.view.LayoutInflater; 5 | 6 | import androidx.annotation.NonNull; 7 | import androidx.lifecycle.ViewModelProvider; 8 | 9 | import org.alfonz.samples.R; 10 | import org.alfonz.samples.alfonzarch.BaseFragment; 11 | import org.alfonz.samples.databinding.FragmentAdapterSamplePagerBinding; 12 | 13 | public class AdapterSamplePagerMultiFragment extends BaseFragment implements AdapterSampleView { 14 | private MessagePagerMultiAdapter mAdapter; 15 | 16 | public static AdapterSamplePagerMultiFragment newInstance() { 17 | return new AdapterSamplePagerMultiFragment(); 18 | } 19 | 20 | @Override 21 | public AdapterSampleViewModel setupViewModel() { 22 | AdapterSampleViewModel viewModel = new ViewModelProvider(this).get(AdapterSampleViewModel.class); 23 | getLifecycle().addObserver(viewModel); 24 | return viewModel; 25 | } 26 | 27 | @Override 28 | public FragmentAdapterSamplePagerBinding inflateBindingLayout(@NonNull LayoutInflater inflater) { 29 | return FragmentAdapterSamplePagerBinding.inflate(inflater); 30 | } 31 | 32 | @Override 33 | public void onActivityCreated(Bundle savedInstanceState) { 34 | super.onActivityCreated(savedInstanceState); 35 | setupAdapter(); 36 | } 37 | 38 | @Override 39 | public void onItemClick(String message) { 40 | String newMessage = getViewModel().addMessage(); 41 | showSnackbar(getString(R.string.adapter_sample_hello, newMessage)); 42 | } 43 | 44 | @Override 45 | public boolean onItemLongClick(String message) { 46 | getViewModel().removeMessage(message); 47 | showToast(getString(R.string.adapter_sample_goodbye, message)); 48 | return true; 49 | } 50 | 51 | private void setupAdapter() { 52 | if (mAdapter == null) { 53 | mAdapter = new MessagePagerMultiAdapter(this, getViewModel()); 54 | getBinding().adapterSamplePager.setAdapter(mAdapter); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzadapter/AdapterSamplePagerSimpleFragment.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzadapter; 2 | 3 | import android.os.Bundle; 4 | import android.view.LayoutInflater; 5 | 6 | import androidx.annotation.NonNull; 7 | import androidx.lifecycle.ViewModelProvider; 8 | 9 | import org.alfonz.samples.R; 10 | import org.alfonz.samples.alfonzarch.BaseFragment; 11 | import org.alfonz.samples.databinding.FragmentAdapterSamplePagerBinding; 12 | 13 | public class AdapterSamplePagerSimpleFragment extends BaseFragment implements AdapterSampleView { 14 | private MessagePagerSimpleAdapter mAdapter; 15 | 16 | public static AdapterSamplePagerSimpleFragment newInstance() { 17 | return new AdapterSamplePagerSimpleFragment(); 18 | } 19 | 20 | @Override 21 | public AdapterSampleViewModel setupViewModel() { 22 | AdapterSampleViewModel viewModel = new ViewModelProvider(this).get(AdapterSampleViewModel.class); 23 | getLifecycle().addObserver(viewModel); 24 | return viewModel; 25 | } 26 | 27 | @Override 28 | public FragmentAdapterSamplePagerBinding inflateBindingLayout(@NonNull LayoutInflater inflater) { 29 | return FragmentAdapterSamplePagerBinding.inflate(inflater); 30 | } 31 | 32 | @Override 33 | public void onActivityCreated(Bundle savedInstanceState) { 34 | super.onActivityCreated(savedInstanceState); 35 | setupAdapter(); 36 | } 37 | 38 | @Override 39 | public void onItemClick(String message) { 40 | String newMessage = getViewModel().addMessage(); 41 | showSnackbar(getString(R.string.adapter_sample_hello, newMessage)); 42 | } 43 | 44 | @Override 45 | public boolean onItemLongClick(String message) { 46 | getViewModel().removeMessage(message); 47 | showToast(getString(R.string.adapter_sample_goodbye, message)); 48 | return true; 49 | } 50 | 51 | private void setupAdapter() { 52 | if (mAdapter == null) { 53 | mAdapter = new MessagePagerSimpleAdapter(this, getViewModel()); 54 | getBinding().adapterSamplePager.setAdapter(mAdapter); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzadapter/AdapterSampleView.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzadapter; 2 | 3 | import org.alfonz.adapter.AdapterView; 4 | import org.alfonz.arch.AlfonzView; 5 | 6 | public interface AdapterSampleView extends AlfonzView, AdapterView { 7 | void onItemClick(String message); 8 | boolean onItemLongClick(String message); 9 | } 10 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzadapter/AdapterSampleViewModel.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzadapter; 2 | 3 | import androidx.databinding.ObservableArrayList; 4 | import androidx.databinding.ObservableList; 5 | import androidx.lifecycle.Lifecycle; 6 | import androidx.lifecycle.LifecycleObserver; 7 | import androidx.lifecycle.OnLifecycleEvent; 8 | 9 | import org.alfonz.samples.alfonzarch.BaseViewModel; 10 | 11 | import java.text.DateFormatSymbols; 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | import java.util.Locale; 15 | 16 | public class AdapterSampleViewModel extends BaseViewModel implements LifecycleObserver { 17 | public final ObservableList messages = new ObservableArrayList<>(); 18 | public final ObservableList numbers = new ObservableArrayList<>(); 19 | public final ObservableList bits = new ObservableArrayList<>(); 20 | 21 | private int mCounter = 0; 22 | 23 | @OnLifecycleEvent(Lifecycle.Event.ON_START) 24 | public void onStart() { 25 | // load data 26 | if (messages.isEmpty()) loadData(); 27 | } 28 | 29 | public String addMessage() { 30 | String[] months = new DateFormatSymbols().getMonths(); 31 | String message = createMessage(months[mCounter % 12]); 32 | messages.add(message); 33 | return message; 34 | } 35 | 36 | public void removeMessage(String message) { 37 | messages.remove(message); 38 | } 39 | 40 | private void loadData() { 41 | loadMessages(); 42 | loadNumbers(); 43 | loadBits(); 44 | } 45 | 46 | private void loadMessages() { 47 | String[] months = new DateFormatSymbols().getMonths(); 48 | List list = new ArrayList<>(); 49 | for (String month : months) { 50 | list.add(createMessage(month)); 51 | } 52 | messages.addAll(list); 53 | } 54 | 55 | private void loadNumbers() { 56 | int a = 0; 57 | int b = 1; 58 | 59 | List list = new ArrayList<>(); 60 | for (int i = 0; i < 16; i++) { 61 | list.add(a); 62 | a = a + b; 63 | b = a - b; 64 | } 65 | numbers.addAll(list); 66 | } 67 | 68 | private void loadBits() { 69 | List list = new ArrayList<>(); 70 | for (int i = 0; i < 6; i++) { 71 | list.add(i % 2 == 0); 72 | } 73 | bits.addAll(list); 74 | } 75 | 76 | private String createMessage(String month) { 77 | return String.format(Locale.US, "%03d %s", ++mCounter, month); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzadapter/MessageListDiffAdapter.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzadapter; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.recyclerview.widget.DiffUtil; 5 | 6 | import org.alfonz.adapter.DataBoundListAdapter; 7 | import org.alfonz.samples.R; 8 | 9 | public class MessageListDiffAdapter extends DataBoundListAdapter { 10 | public MessageListDiffAdapter(AdapterSampleView view) { 11 | super( 12 | view, 13 | item -> { 14 | if (item instanceof String) { 15 | return R.layout.fragment_adapter_sample_list_message_item; 16 | } else if (item instanceof Integer) { 17 | return R.layout.fragment_adapter_sample_list_number_item; 18 | } else if (item instanceof Boolean) { 19 | return R.layout.fragment_adapter_sample_list_bit_item; 20 | } 21 | throw new IllegalArgumentException("Unknown item type " + item); 22 | }, 23 | new DiffUtil.ItemCallback() { 24 | @Override 25 | public boolean areItemsTheSame(@NonNull Object oldItem, @NonNull Object newItem) { 26 | return oldItem.equals(newItem); 27 | } 28 | 29 | @Override 30 | public boolean areContentsTheSame(@NonNull Object oldItem, @NonNull Object newItem) { 31 | return oldItem.equals(newItem); 32 | } 33 | } 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzadapter/MessageListMultiAdapter.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzadapter; 2 | 3 | import org.alfonz.adapter.MultiDataBoundRecyclerAdapter; 4 | import org.alfonz.samples.R; 5 | 6 | public class MessageListMultiAdapter extends MultiDataBoundRecyclerAdapter { 7 | public MessageListMultiAdapter(AdapterSampleView view, AdapterSampleViewModel viewModel) { 8 | super( 9 | view, 10 | viewModel.messages, 11 | viewModel.numbers, 12 | viewModel.bits 13 | ); 14 | } 15 | 16 | @Override 17 | public int getItemLayoutId(int position) { 18 | Object item = getItem(position); 19 | if (item instanceof String) { 20 | return R.layout.fragment_adapter_sample_list_message_item; 21 | } else if (item instanceof Integer) { 22 | return R.layout.fragment_adapter_sample_list_number_item; 23 | } else if (item instanceof Boolean) { 24 | return R.layout.fragment_adapter_sample_list_bit_item; 25 | } 26 | throw new IllegalArgumentException("Unknown item type " + item); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzadapter/MessageListSimpleAdapter.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzadapter; 2 | 3 | import org.alfonz.adapter.SimpleDataBoundRecyclerAdapter; 4 | import org.alfonz.samples.R; 5 | 6 | public class MessageListSimpleAdapter extends SimpleDataBoundRecyclerAdapter { 7 | public MessageListSimpleAdapter(AdapterSampleView view, AdapterSampleViewModel viewModel) { 8 | super( 9 | R.layout.fragment_adapter_sample_list_message_item, 10 | view, 11 | viewModel.messages 12 | ); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzadapter/MessagePagerMultiAdapter.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzadapter; 2 | 3 | import org.alfonz.adapter.MultiDataBoundPagerAdapter; 4 | import org.alfonz.samples.R; 5 | 6 | public class MessagePagerMultiAdapter extends MultiDataBoundPagerAdapter { 7 | public MessagePagerMultiAdapter(AdapterSampleView view, AdapterSampleViewModel viewModel) { 8 | super( 9 | view, 10 | viewModel.messages, 11 | viewModel.numbers, 12 | viewModel.bits 13 | ); 14 | } 15 | 16 | @Override 17 | public int getItemLayoutId(int position) { 18 | Object item = getItem(position); 19 | if (item instanceof String) { 20 | return R.layout.fragment_adapter_sample_pager_message_item; 21 | } else if (item instanceof Integer) { 22 | return R.layout.fragment_adapter_sample_pager_number_item; 23 | } else if (item instanceof Boolean) { 24 | return R.layout.fragment_adapter_sample_pager_bit_item; 25 | } 26 | throw new IllegalArgumentException("Unknown item type " + item); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzadapter/MessagePagerSimpleAdapter.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzadapter; 2 | 3 | import org.alfonz.adapter.SimpleDataBoundPagerAdapter; 4 | import org.alfonz.samples.R; 5 | 6 | public class MessagePagerSimpleAdapter extends SimpleDataBoundPagerAdapter { 7 | public MessagePagerSimpleAdapter(AdapterSampleView view, AdapterSampleViewModel viewModel) { 8 | super( 9 | R.layout.fragment_adapter_sample_pager_message_item, 10 | view, 11 | viewModel.messages 12 | ); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzarch/ArchSampleActivity.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzarch; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | 7 | import org.alfonz.arch.widget.ToolbarIndicator; 8 | import org.alfonz.samples.R; 9 | 10 | public class ArchSampleActivity extends BaseActivity { 11 | public static Intent newIntent(Context context) { 12 | Intent intent = new Intent(context, ArchSampleActivity.class); 13 | intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 14 | return intent; 15 | } 16 | 17 | @Override 18 | public void onCreate(Bundle savedInstanceState) { 19 | super.onCreate(savedInstanceState); 20 | setContentView(R.layout.activity_arch_sample); 21 | setupActionBar(ToolbarIndicator.BACK); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzarch/ArchSampleFragment.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzarch; 2 | 3 | import android.content.Intent; 4 | import android.view.LayoutInflater; 5 | 6 | import androidx.annotation.NonNull; 7 | import androidx.lifecycle.ViewModelProvider; 8 | 9 | import org.alfonz.samples.databinding.FragmentArchSampleBinding; 10 | 11 | public class ArchSampleFragment extends BaseFragment implements ArchSampleView { 12 | @Override 13 | public ArchSampleViewModel setupViewModel() { 14 | ArchSampleViewModelFactory factory = new ArchSampleViewModelFactory(getActivity().getIntent().getExtras()); 15 | ArchSampleViewModel viewModel = new ViewModelProvider(this, factory).get(ArchSampleViewModel.class); 16 | getLifecycle().addObserver(viewModel); 17 | return viewModel; 18 | } 19 | 20 | @Override 21 | public FragmentArchSampleBinding inflateBindingLayout(@NonNull LayoutInflater inflater) { 22 | return FragmentArchSampleBinding.inflate(inflater); 23 | } 24 | 25 | @Override 26 | public void onClick() { 27 | getViewModel().updateMessage(); 28 | } 29 | 30 | @Override 31 | public boolean onLongClick() { 32 | Intent intent = ArchSampleViewModelActivity.newIntent(getActivity()); 33 | getActivity().startActivity(intent); 34 | return true; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzarch/ArchSampleView.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzarch; 2 | 3 | import org.alfonz.arch.AlfonzView; 4 | 5 | public interface ArchSampleView extends AlfonzView { 6 | void onClick(); 7 | boolean onLongClick(); 8 | } 9 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzarch/ArchSampleViewModel.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzarch; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.os.AsyncTask; 5 | import android.os.Bundle; 6 | 7 | import androidx.lifecycle.Lifecycle; 8 | import androidx.lifecycle.LifecycleObserver; 9 | import androidx.lifecycle.MutableLiveData; 10 | import androidx.lifecycle.OnLifecycleEvent; 11 | 12 | import org.alfonz.utility.NetworkUtility; 13 | import org.alfonz.view.StatefulLayout; 14 | 15 | public class ArchSampleViewModel extends BaseViewModel implements LifecycleObserver { 16 | public final MutableLiveData state = new MutableLiveData<>(); 17 | public final MutableLiveData message = new MutableLiveData<>(); 18 | 19 | public ArchSampleViewModel(Bundle extras) { 20 | } 21 | 22 | @OnLifecycleEvent(Lifecycle.Event.ON_START) 23 | public void onStart() { 24 | // load data 25 | if (message.getValue() == null) loadData(); 26 | } 27 | 28 | public void updateMessage() { 29 | String s = message.getValue(); 30 | s += "o"; 31 | message.setValue(s); 32 | } 33 | 34 | private void loadData() { 35 | if (NetworkUtility.isOnline(getApplicationContext())) { 36 | // show progress 37 | state.setValue(StatefulLayout.PROGRESS); 38 | 39 | // load data 40 | @SuppressLint("StaticFieldLeak") 41 | AsyncTask task = new AsyncTask() { 42 | @Override 43 | protected String doInBackground(Void... voids) { 44 | try { 45 | Thread.sleep(2000L); 46 | return "Hello"; 47 | } catch (InterruptedException e) { 48 | e.printStackTrace(); 49 | return null; 50 | } 51 | } 52 | 53 | @Override 54 | protected void onPostExecute(String s) { 55 | onLoadData(s); 56 | } 57 | }.execute(); 58 | } else { 59 | state.setValue(StatefulLayout.OFFLINE); 60 | } 61 | } 62 | 63 | private void onLoadData(String s) { 64 | // save data 65 | message.setValue(s); 66 | 67 | // show content 68 | if (message.getValue() != null) { 69 | state.setValue(StatefulLayout.CONTENT); 70 | } else { 71 | state.setValue(StatefulLayout.EMPTY); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzarch/ArchSampleViewModelActivity.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzarch; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.view.LayoutInflater; 7 | 8 | import androidx.annotation.NonNull; 9 | import androidx.lifecycle.ViewModelProvider; 10 | 11 | import org.alfonz.arch.AlfonzBindingActivity; 12 | import org.alfonz.arch.widget.ToolbarIndicator; 13 | import org.alfonz.samples.databinding.ActivityArchSampleViewModelBinding; 14 | 15 | public class ArchSampleViewModelActivity extends AlfonzBindingActivity implements ArchSampleView { 16 | public static Intent newIntent(Context context) { 17 | Intent intent = new Intent(context, ArchSampleViewModelActivity.class); 18 | intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 19 | return intent; 20 | } 21 | 22 | @Override 23 | public ArchSampleViewModel setupViewModel() { 24 | ArchSampleViewModelFactory factory = new ArchSampleViewModelFactory(getIntent().getExtras()); 25 | ArchSampleViewModel viewModel = new ViewModelProvider(this, factory).get(ArchSampleViewModel.class); 26 | getLifecycle().addObserver(viewModel); 27 | return viewModel; 28 | } 29 | 30 | @Override 31 | public ActivityArchSampleViewModelBinding inflateBindingLayout(@NonNull LayoutInflater inflater) { 32 | return ActivityArchSampleViewModelBinding.inflate(inflater); 33 | } 34 | 35 | @Override 36 | public void onCreate(Bundle savedInstanceState) { 37 | super.onCreate(savedInstanceState); 38 | setupActionBar(ToolbarIndicator.BACK); 39 | } 40 | 41 | @Override 42 | public void onClick() { 43 | getViewModel().updateMessage(); 44 | } 45 | 46 | @Override 47 | public boolean onLongClick() { 48 | getViewModel().updateMessage(); 49 | return true; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzarch/ArchSampleViewModelFactory.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzarch; 2 | 3 | import android.os.Bundle; 4 | 5 | import androidx.annotation.NonNull; 6 | import androidx.lifecycle.ViewModel; 7 | import androidx.lifecycle.ViewModelProvider; 8 | 9 | public class ArchSampleViewModelFactory extends ViewModelProvider.NewInstanceFactory { 10 | private final Bundle mExtras; 11 | 12 | public ArchSampleViewModelFactory(Bundle extras) { 13 | mExtras = extras; 14 | } 15 | 16 | @NonNull 17 | @Override 18 | @SuppressWarnings("unchecked") 19 | public T create(@NonNull Class modelClass) { 20 | return (T) new ArchSampleViewModel(mExtras); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzarch/BaseActivity.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzarch; 2 | 3 | import org.alfonz.arch.AlfonzActivity; 4 | 5 | public abstract class BaseActivity extends AlfonzActivity { 6 | } 7 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzarch/BaseFragment.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzarch; 2 | 3 | import android.os.Bundle; 4 | import android.widget.Toast; 5 | 6 | import androidx.databinding.ViewDataBinding; 7 | 8 | import com.google.android.material.snackbar.Snackbar; 9 | 10 | import org.alfonz.arch.AlfonzBindingFragment; 11 | import org.alfonz.samples.alfonzarch.event.SnackbarEvent; 12 | import org.alfonz.samples.alfonzarch.event.ToastEvent; 13 | 14 | import leakcanary.AppWatcher; 15 | 16 | public abstract class BaseFragment extends AlfonzBindingFragment { 17 | @Override 18 | public void onCreate(Bundle savedInstanceState) { 19 | super.onCreate(savedInstanceState); 20 | setHasOptionsMenu(true); 21 | setupObservers(); 22 | } 23 | 24 | @Override 25 | public void onDestroy() { 26 | super.onDestroy(); 27 | 28 | // leak canary watcher 29 | AppWatcher.INSTANCE.getObjectWatcher().watch(this, "Watch Fragment"); 30 | if (getActivity().isFinishing()) 31 | AppWatcher.INSTANCE.getObjectWatcher().watch(getViewModel(), "Watch ViewModel"); 32 | } 33 | 34 | public void showToast(String message) { 35 | Toast.makeText(getActivity(), message, Toast.LENGTH_LONG).show(); 36 | } 37 | 38 | public void showSnackbar(String message) { 39 | if (getView() != null) { 40 | Snackbar.make(getView(), message, Snackbar.LENGTH_LONG).show(); 41 | } 42 | } 43 | 44 | private void setupObservers() { 45 | getViewModel().observeEvent(this, ToastEvent.class, toastEvent -> showToast(toastEvent.message)); 46 | getViewModel().observeEvent(this, SnackbarEvent.class, snackbarEvent -> showSnackbar(snackbarEvent.message)); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzarch/BaseViewModel.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzarch; 2 | 3 | import android.content.Context; 4 | 5 | import org.alfonz.arch.AlfonzViewModel; 6 | import org.alfonz.samples.SamplesApplication; 7 | import org.alfonz.samples.alfonzarch.event.ToastEvent; 8 | 9 | public abstract class BaseViewModel extends AlfonzViewModel { 10 | public Context getApplicationContext() { 11 | return SamplesApplication.getContext(); 12 | } 13 | 14 | public void handleError(String message) { 15 | sendEvent(new ToastEvent(message)); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzarch/event/SnackbarEvent.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzarch.event; 2 | 3 | import org.alfonz.arch.event.Event; 4 | 5 | public class SnackbarEvent extends Event { 6 | public final String message; 7 | 8 | public SnackbarEvent(String message) { 9 | this.message = message; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzarch/event/ToastEvent.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzarch.event; 2 | 3 | import org.alfonz.arch.event.Event; 4 | 5 | public class ToastEvent extends Event { 6 | public final String message; 7 | 8 | public ToastEvent(String message) { 9 | this.message = message; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzgraphics/GraphicsSampleActivity.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzgraphics; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | 7 | import org.alfonz.arch.widget.ToolbarIndicator; 8 | import org.alfonz.samples.R; 9 | import org.alfonz.samples.alfonzarch.BaseActivity; 10 | 11 | public class GraphicsSampleActivity extends BaseActivity { 12 | public static Intent newIntent(Context context) { 13 | Intent intent = new Intent(context, GraphicsSampleActivity.class); 14 | intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 15 | return intent; 16 | } 17 | 18 | @Override 19 | public void onCreate(Bundle savedInstanceState) { 20 | super.onCreate(savedInstanceState); 21 | setContentView(R.layout.activity_graphics_sample); 22 | setupActionBar(ToolbarIndicator.BACK); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzgraphics/GraphicsSampleView.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzgraphics; 2 | 3 | import org.alfonz.arch.AlfonzView; 4 | 5 | public interface GraphicsSampleView extends AlfonzView { 6 | } 7 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzgraphics/GraphicsSampleViewModel.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzgraphics; 2 | 3 | import org.alfonz.samples.alfonzarch.BaseViewModel; 4 | 5 | public class GraphicsSampleViewModel extends BaseViewModel { 6 | } 7 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzmedia/MediaSampleActivity.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzmedia; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | 7 | import org.alfonz.arch.widget.ToolbarIndicator; 8 | import org.alfonz.samples.R; 9 | import org.alfonz.samples.alfonzarch.BaseActivity; 10 | 11 | public class MediaSampleActivity extends BaseActivity { 12 | public static Intent newIntent(Context context) { 13 | Intent intent = new Intent(context, MediaSampleActivity.class); 14 | intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 15 | return intent; 16 | } 17 | 18 | @Override 19 | public void onCreate(Bundle savedInstanceState) { 20 | super.onCreate(savedInstanceState); 21 | setContentView(R.layout.activity_media_sample); 22 | setupActionBar(ToolbarIndicator.BACK); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzmedia/MediaSampleView.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzmedia; 2 | 3 | import org.alfonz.arch.AlfonzView; 4 | 5 | public interface MediaSampleView extends AlfonzView { 6 | void onButtonPlaySoundClick(); 7 | void onButtonStopSoundClick(); 8 | void onButtonPickImageFromCameraClick(); 9 | void onButtonPickImageFromGalleryClick(); 10 | } 11 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzmedia/MediaSampleViewModel.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzmedia; 2 | 3 | import android.graphics.Bitmap; 4 | 5 | import androidx.lifecycle.MutableLiveData; 6 | 7 | import org.alfonz.samples.alfonzarch.BaseViewModel; 8 | import org.alfonz.samples.alfonzutility.utility.PermissionRationaleHandler; 9 | import org.alfonz.utility.PermissionManager; 10 | 11 | public class MediaSampleViewModel extends BaseViewModel { 12 | public final MutableLiveData bitmap = new MutableLiveData<>(); 13 | 14 | public final PermissionManager permissionManager = new PermissionManager(new PermissionRationaleHandler()); 15 | 16 | public void updateBitmap(Bitmap bitmap) { 17 | this.bitmap.setValue(bitmap); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzrest/RestSampleActivity.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzrest; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | 7 | import org.alfonz.arch.widget.ToolbarIndicator; 8 | import org.alfonz.samples.R; 9 | import org.alfonz.samples.alfonzarch.BaseActivity; 10 | 11 | public class RestSampleActivity extends BaseActivity { 12 | public static Intent newIntent(Context context) { 13 | Intent intent = new Intent(context, RestSampleActivity.class); 14 | intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 15 | return intent; 16 | } 17 | 18 | @Override 19 | public void onCreate(Bundle savedInstanceState) { 20 | super.onCreate(savedInstanceState); 21 | setContentView(R.layout.activity_rest_sample); 22 | setupActionBar(ToolbarIndicator.BACK); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzrest/RestSampleFragment.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzrest; 2 | 3 | import android.view.LayoutInflater; 4 | 5 | import androidx.annotation.NonNull; 6 | import androidx.lifecycle.ViewModelProvider; 7 | 8 | import org.alfonz.samples.alfonzarch.BaseFragment; 9 | import org.alfonz.samples.databinding.FragmentRestSampleBinding; 10 | 11 | public class RestSampleFragment extends BaseFragment implements RestSampleView { 12 | @Override 13 | public RestSampleRxViewModel setupViewModel() { 14 | RestSampleRxViewModel viewModel = new ViewModelProvider(this).get(RestSampleRxViewModel.class); 15 | getLifecycle().addObserver(viewModel); 16 | return viewModel; 17 | } 18 | 19 | @Override 20 | public FragmentRestSampleBinding inflateBindingLayout(@NonNull LayoutInflater inflater) { 21 | return FragmentRestSampleBinding.inflate(inflater); 22 | } 23 | 24 | @Override 25 | public void onClick() { 26 | getViewModel().refreshData(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzrest/RestSampleView.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzrest; 2 | 3 | import org.alfonz.arch.AlfonzView; 4 | 5 | public interface RestSampleView extends AlfonzView { 6 | void onClick(); 7 | } 8 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzrest/entity/ErrorEntity.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzrest.entity; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | public class ErrorEntity { 6 | @SerializedName("message") private String message; 7 | @SerializedName("documentation_url") private String documentationUrl; 8 | 9 | public ErrorEntity() { 10 | } 11 | 12 | public String getMessage() { 13 | return message; 14 | } 15 | 16 | public void setMessage(String message) { 17 | this.message = message; 18 | } 19 | 20 | public String getDocumentationUrl() { 21 | return documentationUrl; 22 | } 23 | 24 | public void setDocumentationUrl(String documentationUrl) { 25 | this.documentationUrl = documentationUrl; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzrest/entity/OwnerEntity.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzrest.entity; 2 | 3 | import com.google.gson.annotations.SerializedName; 4 | 5 | public class OwnerEntity { 6 | @SerializedName("id") private long id; 7 | @SerializedName("login") private String login; 8 | @SerializedName("avatar_url") private String avatarUrl; 9 | 10 | public OwnerEntity() { 11 | } 12 | 13 | public long getId() { 14 | return id; 15 | } 16 | 17 | public void setId(long id) { 18 | this.id = id; 19 | } 20 | 21 | public String getLogin() { 22 | return login; 23 | } 24 | 25 | public void setLogin(String login) { 26 | this.login = login; 27 | } 28 | 29 | public String getAvatarUrl() { 30 | return avatarUrl; 31 | } 32 | 33 | public void setAvatarUrl(String avatarUrl) { 34 | this.avatarUrl = avatarUrl; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzrest/rest/RestHttpException.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzrest.rest; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | import org.alfonz.rest.HttpException; 6 | import org.alfonz.samples.alfonzrest.entity.ErrorEntity; 7 | 8 | import java.io.IOException; 9 | import java.lang.annotation.Annotation; 10 | 11 | import okhttp3.ResponseBody; 12 | import retrofit2.Converter; 13 | import retrofit2.Response; 14 | 15 | public class RestHttpException extends HttpException { 16 | public RestHttpException(Response response) { 17 | super(response); 18 | } 19 | 20 | @Override 21 | public Object parseError(@NonNull Response response) { 22 | try { 23 | Converter converter = RetrofitClient.getRetrofit().responseBodyConverter(ErrorEntity.class, new Annotation[0]); 24 | return converter.convert(response.errorBody()); 25 | } catch (IOException | NullPointerException e) { 26 | e.printStackTrace(); 27 | ErrorEntity error = new ErrorEntity(); 28 | error.setMessage("Unknown error"); 29 | return error; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzrest/rest/RestHttpLogger.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzrest.rest; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | import org.alfonz.rest.HttpLogger; 6 | import org.alfonz.utility.Logcat; 7 | 8 | public class RestHttpLogger implements HttpLogger { 9 | @Override 10 | public void logSuccess(@NonNull String message) { 11 | Logcat.d(message); 12 | } 13 | 14 | @Override 15 | public void logError(@NonNull String message) { 16 | Logcat.d(message); 17 | } 18 | 19 | @Override 20 | public void logFail(@NonNull String message) { 21 | Logcat.d(message); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzrest/rest/RestResponseHandler.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzrest.rest; 2 | 3 | import android.net.ParseException; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | import com.google.gson.JsonParseException; 8 | import com.google.gson.stream.MalformedJsonException; 9 | 10 | import org.alfonz.rest.HttpException; 11 | import org.alfonz.rest.ResponseHandler; 12 | import org.alfonz.samples.R; 13 | import org.alfonz.samples.SamplesApplication; 14 | import org.alfonz.samples.alfonzrest.entity.ErrorEntity; 15 | 16 | import java.io.FileNotFoundException; 17 | import java.net.SocketTimeoutException; 18 | import java.net.UnknownHostException; 19 | 20 | import retrofit2.Response; 21 | 22 | public class RestResponseHandler implements ResponseHandler { 23 | @Override 24 | public boolean isSuccess(@NonNull Response response) { 25 | return response.isSuccessful(); 26 | } 27 | 28 | @Override 29 | public String getErrorMessage(@NonNull HttpException exception) { 30 | ErrorEntity error = (ErrorEntity) exception.error(); 31 | return error.getMessage(); 32 | } 33 | 34 | @Override 35 | public String getFailMessage(@NonNull Throwable throwable) { 36 | int resId; 37 | 38 | if (throwable instanceof UnknownHostException) 39 | resId = R.string.global_network_unknown_host; 40 | else if (throwable instanceof FileNotFoundException) 41 | resId = R.string.global_network_not_found; 42 | else if (throwable instanceof SocketTimeoutException) 43 | resId = R.string.global_network_timeout; 44 | else if (throwable instanceof JsonParseException) 45 | resId = R.string.global_network_parse_fail; 46 | else if (throwable instanceof MalformedJsonException) 47 | resId = R.string.global_network_parse_fail; 48 | else if (throwable instanceof ParseException) 49 | resId = R.string.global_network_parse_fail; 50 | else if (throwable instanceof NumberFormatException) 51 | resId = R.string.global_network_parse_fail; 52 | else if (throwable instanceof ClassCastException) 53 | resId = R.string.global_network_parse_fail; 54 | else 55 | resId = R.string.global_network_fail; 56 | 57 | return SamplesApplication.getContext().getString(resId); 58 | } 59 | 60 | @Override 61 | public HttpException createHttpException(@NonNull Response response) { 62 | return new RestHttpException(response); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzrest/rest/http/HeaderRequestInterceptor.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzrest.rest.http; 2 | 3 | import androidx.annotation.NonNull; 4 | 5 | import java.io.IOException; 6 | 7 | import okhttp3.Interceptor; 8 | import okhttp3.Request; 9 | import okhttp3.Response; 10 | 11 | public class HeaderRequestInterceptor implements Interceptor { 12 | @NonNull 13 | @Override 14 | public Response intercept(Chain chain) throws IOException { 15 | Request.Builder builder = chain.request().newBuilder(); 16 | builder.addHeader("Accept", "application/json"); 17 | builder.addHeader("Accept-Charset", "utf-8"); 18 | builder.addHeader("Content-Type", "application/json"); 19 | Request request = builder.build(); 20 | return chain.proceed(request); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzrest/rest/router/RepoRouter.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzrest.rest.router; 2 | 3 | import org.alfonz.samples.alfonzrest.entity.RepoEntity; 4 | import org.alfonz.samples.alfonzrest.rest.RetrofitClient; 5 | 6 | import retrofit2.Call; 7 | import retrofit2.http.GET; 8 | import retrofit2.http.Path; 9 | 10 | public class RepoRouter { 11 | public static final String REPO_CALL_TYPE = "repo"; 12 | 13 | private static volatile RepoService sService; 14 | 15 | public interface RepoService { 16 | @GET("repos/{owner}/{repo}") 17 | Call repo(@Path("owner") String owner, @Path("repo") String repo); 18 | } 19 | 20 | private RepoRouter() {} 21 | 22 | public static RepoService getService() { 23 | if (sService == null) { 24 | synchronized (RepoRouter.class) { 25 | if (sService == null) { 26 | sService = RetrofitClient.createService(RepoService.class); 27 | } 28 | } 29 | } 30 | return sService; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzrest/rest/router/RepoRxRouter.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzrest.rest.router; 2 | 3 | import org.alfonz.samples.alfonzrest.entity.RepoEntity; 4 | import org.alfonz.samples.alfonzrest.rest.RetrofitClient; 5 | 6 | import io.reactivex.rxjava3.core.Single; 7 | import retrofit2.Response; 8 | import retrofit2.http.GET; 9 | import retrofit2.http.Path; 10 | 11 | public class RepoRxRouter { 12 | public static final String REPO_CALL_TYPE = "repo"; 13 | 14 | private static volatile RepoService sService; 15 | 16 | public interface RepoService { 17 | @GET("repos/{owner}/{repo}") 18 | Single> repo(@Path("owner") String owner, @Path("repo") String repo); 19 | } 20 | 21 | private RepoRxRouter() {} 22 | 23 | public static RepoService getService() { 24 | if (sService == null) { 25 | synchronized (RepoRxRouter.class) { 26 | if (sService == null) { 27 | sService = RetrofitClient.createService(RepoService.class); 28 | } 29 | } 30 | } 31 | return sService; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzrx/RxSampleActivity.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzrx; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | 7 | import org.alfonz.arch.widget.ToolbarIndicator; 8 | import org.alfonz.samples.R; 9 | import org.alfonz.samples.alfonzarch.BaseActivity; 10 | 11 | public class RxSampleActivity extends BaseActivity { 12 | public static Intent newIntent(Context context) { 13 | Intent intent = new Intent(context, RxSampleActivity.class); 14 | intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 15 | return intent; 16 | } 17 | 18 | @Override 19 | public void onCreate(Bundle savedInstanceState) { 20 | super.onCreate(savedInstanceState); 21 | setContentView(R.layout.activity_rx_sample); 22 | setupActionBar(ToolbarIndicator.BACK); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzrx/RxSampleFragment.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzrx; 2 | 3 | import android.view.LayoutInflater; 4 | 5 | import androidx.annotation.NonNull; 6 | import androidx.lifecycle.ViewModelProvider; 7 | 8 | import org.alfonz.rx.RxBus; 9 | import org.alfonz.samples.alfonzarch.BaseFragment; 10 | import org.alfonz.samples.databinding.FragmentRxSampleBinding; 11 | 12 | public class RxSampleFragment extends BaseFragment implements RxSampleView { 13 | @Override 14 | public RxSampleViewModel setupViewModel() { 15 | return new ViewModelProvider(this).get(RxSampleViewModel.class); 16 | } 17 | 18 | @Override 19 | public FragmentRxSampleBinding inflateBindingLayout(@NonNull LayoutInflater inflater) { 20 | return FragmentRxSampleBinding.inflate(inflater); 21 | } 22 | 23 | @Override 24 | public void onButtonRunClick() { 25 | getViewModel().run(); 26 | } 27 | 28 | @Override 29 | public void onButtonTerminateClick() { 30 | getViewModel().terminate(); 31 | } 32 | 33 | @Override 34 | public void onButtonIsRunningClick() { 35 | getViewModel().isRunning(); 36 | } 37 | 38 | @Override 39 | public void onButtonEventClick() { 40 | RxBus.getInstance().send(System.currentTimeMillis()); 41 | RxBus.getInstance().send("Dummy"); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzrx/RxSampleView.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzrx; 2 | 3 | import org.alfonz.arch.AlfonzView; 4 | 5 | public interface RxSampleView extends AlfonzView { 6 | void onButtonRunClick(); 7 | void onButtonTerminateClick(); 8 | void onButtonIsRunningClick(); 9 | void onButtonEventClick(); 10 | } 11 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzutility/UtilitySampleActivity.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzutility; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | 7 | import org.alfonz.arch.widget.ToolbarIndicator; 8 | import org.alfonz.samples.R; 9 | import org.alfonz.samples.alfonzarch.BaseActivity; 10 | 11 | public class UtilitySampleActivity extends BaseActivity { 12 | public static Intent newIntent(Context context) { 13 | Intent intent = new Intent(context, UtilitySampleActivity.class); 14 | intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 15 | return intent; 16 | } 17 | 18 | @Override 19 | public void onCreate(Bundle savedInstanceState) { 20 | super.onCreate(savedInstanceState); 21 | setContentView(R.layout.activity_utility_sample); 22 | setupActionBar(ToolbarIndicator.BACK); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzutility/UtilitySampleService.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzutility; 2 | 3 | import android.app.IntentService; 4 | import android.content.Intent; 5 | 6 | import org.alfonz.utility.Logcat; 7 | 8 | public class UtilitySampleService extends IntentService { 9 | public UtilitySampleService() { 10 | super("UtilitySampleService"); 11 | } 12 | 13 | @Override 14 | public void onCreate() { 15 | super.onCreate(); 16 | Logcat.d(""); 17 | } 18 | 19 | @Override 20 | protected void onHandleIntent(Intent intent) { 21 | long endTime = System.currentTimeMillis() + 5000L; 22 | while (System.currentTimeMillis() < endTime) { 23 | synchronized (this) { 24 | try { 25 | // do nothing 26 | wait(endTime - System.currentTimeMillis()); 27 | } catch (InterruptedException e) { 28 | e.printStackTrace(); 29 | } 30 | } 31 | } 32 | } 33 | 34 | @Override 35 | public void onDestroy() { 36 | super.onDestroy(); 37 | Logcat.d(""); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzutility/UtilitySampleView.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzutility; 2 | 3 | import org.alfonz.arch.AlfonzView; 4 | 5 | public interface UtilitySampleView extends AlfonzView { 6 | void onButtonShowKeyboardClick(); 7 | void onButtonHideKeyboardClick(); 8 | void onButtonStartWebClick(); 9 | void onButtonStartStoreClick(); 10 | void onButtonStartShareClick(); 11 | void onButtonStartEmailClick(); 12 | void onButtonStartSmsClick(); 13 | void onButtonStartCallClick(); 14 | void onButtonStartMapCoordinatesClick(); 15 | void onButtonStartMapSearchClick(); 16 | void onButtonStartNavigationClick(); 17 | void onButtonStartCalendarClick(); 18 | void onButtonStartNotificationSettingsClick(); 19 | void onButtonIsCallableClick(); 20 | void onButtonPermissionClick(); 21 | void onButtonPermissionsClick(); 22 | void onButtonLogcatClick(); 23 | void onButtonDownloadClick(); 24 | void onButtonZipClick(); 25 | } 26 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzutility/utility/PermissionRationaleHandler.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzutility.utility; 2 | 3 | import android.Manifest; 4 | import android.view.View; 5 | 6 | import androidx.annotation.NonNull; 7 | 8 | import com.google.android.material.snackbar.Snackbar; 9 | 10 | import org.alfonz.samples.R; 11 | import org.alfonz.samples.SamplesApplication; 12 | import org.alfonz.utility.PermissionManager; 13 | 14 | public class PermissionRationaleHandler implements PermissionManager.RationaleHandler { 15 | @Override 16 | public String getRationaleMessage(@NonNull String permission) { 17 | int resId; 18 | 19 | switch (permission) { 20 | case Manifest.permission.READ_EXTERNAL_STORAGE: 21 | resId = R.string.permission_read_external_storage; 22 | break; 23 | case Manifest.permission.WRITE_EXTERNAL_STORAGE: 24 | resId = R.string.permission_write_external_storage; 25 | break; 26 | case Manifest.permission.ACCESS_COARSE_LOCATION: 27 | case Manifest.permission.ACCESS_FINE_LOCATION: 28 | resId = R.string.permission_access_location; 29 | break; 30 | default: 31 | resId = R.string.permission_unknown; 32 | } 33 | 34 | return SamplesApplication.getContext().getString(resId); 35 | } 36 | 37 | @Override 38 | public void showRationale(@NonNull View rootView, @NonNull String rationaleMessage, @NonNull PermissionManager.ConfirmAction confirmAction) { 39 | Snackbar 40 | .make(rootView, rationaleMessage, Snackbar.LENGTH_INDEFINITE) 41 | .setAction(android.R.string.ok, view -> confirmAction.run()) 42 | .show(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzview/ViewSampleActivity.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzview; 2 | 3 | import android.content.Context; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | 7 | import org.alfonz.arch.widget.ToolbarIndicator; 8 | import org.alfonz.samples.R; 9 | import org.alfonz.samples.alfonzarch.BaseActivity; 10 | 11 | public class ViewSampleActivity extends BaseActivity { 12 | public static Intent newIntent(Context context) { 13 | Intent intent = new Intent(context, ViewSampleActivity.class); 14 | intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 15 | return intent; 16 | } 17 | 18 | @Override 19 | public void onCreate(Bundle savedInstanceState) { 20 | super.onCreate(savedInstanceState); 21 | setContentView(R.layout.activity_view_sample); 22 | setupActionBar(ToolbarIndicator.BACK); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzview/ViewSampleFragment.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzview; 2 | 3 | import android.os.Bundle; 4 | import android.view.LayoutInflater; 5 | 6 | import androidx.annotation.NonNull; 7 | import androidx.lifecycle.ViewModelProvider; 8 | 9 | import org.alfonz.samples.alfonzarch.BaseFragment; 10 | import org.alfonz.samples.databinding.FragmentViewSampleBinding; 11 | import org.alfonz.utility.Logcat; 12 | 13 | public class ViewSampleFragment extends BaseFragment implements ViewSampleView { 14 | @Override 15 | public ViewSampleViewModel setupViewModel() { 16 | ViewSampleViewModel viewModel = new ViewModelProvider(this).get(ViewSampleViewModel.class); 17 | getLifecycle().addObserver(viewModel); 18 | return viewModel; 19 | } 20 | 21 | @Override 22 | public FragmentViewSampleBinding inflateBindingLayout(@NonNull LayoutInflater inflater) { 23 | return FragmentViewSampleBinding.inflate(inflater); 24 | } 25 | 26 | @Override 27 | public void onActivityCreated(Bundle savedInstanceState) { 28 | super.onActivityCreated(savedInstanceState); 29 | setupScrollview(); 30 | } 31 | 32 | private void setupScrollview() { 33 | getBinding().viewSampleScrollview.setOnScrollViewListener((scrollView, x, y, oldx, oldy) -> Logcat.d("%d", y)); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzview/ViewSampleView.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzview; 2 | 3 | import org.alfonz.arch.AlfonzView; 4 | 5 | public interface ViewSampleView extends AlfonzView { 6 | } 7 | -------------------------------------------------------------------------------- /samples/src/main/java/org/alfonz/samples/alfonzview/ViewSampleViewModel.java: -------------------------------------------------------------------------------- 1 | package org.alfonz.samples.alfonzview; 2 | 3 | import androidx.lifecycle.Lifecycle; 4 | import androidx.lifecycle.LifecycleObserver; 5 | import androidx.lifecycle.MutableLiveData; 6 | import androidx.lifecycle.OnLifecycleEvent; 7 | 8 | import org.alfonz.samples.alfonzarch.BaseViewModel; 9 | import org.alfonz.view.StatefulLayout; 10 | 11 | public class ViewSampleViewModel extends BaseViewModel implements LifecycleObserver { 12 | public final MutableLiveData state = new MutableLiveData<>(); 13 | public final MutableLiveData message = new MutableLiveData<>(); 14 | 15 | @OnLifecycleEvent(Lifecycle.Event.ON_START) 16 | public void onStart() { 17 | // load data 18 | if (message.getValue() == null) loadData(); 19 | } 20 | 21 | private void loadData() { 22 | // set message 23 | StringBuilder s = new StringBuilder(); 24 | for (int i = 0; i < 8; i++) { 25 | s.append("lorem ipsum dolor sit amet "); 26 | } 27 | message.setValue(s.toString().trim()); 28 | 29 | // set state 30 | state.setValue(StatefulLayout.CONTENT); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /samples/src/main/res/drawable-nodpi/photo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/petrnohejl/alfonz/ed7e04b2dcb3476a4a085690dd0b618b91c61b4b/samples/src/main/res/drawable-nodpi/photo.png -------------------------------------------------------------------------------- /samples/src/main/res/drawable/selector_clickable_item_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 11 | 14 | 16 | 17 | -------------------------------------------------------------------------------- /samples/src/main/res/layout/activity_adapter_sample.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /samples/src/main/res/layout/activity_arch_sample.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /samples/src/main/res/layout/activity_arch_sample_view_model.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 11 | 14 | 15 | 16 | 20 | 21 | 22 | 23 | 31 | 32 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /samples/src/main/res/layout/activity_graphics_sample.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /samples/src/main/res/layout/activity_media_sample.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /samples/src/main/res/layout/activity_rest_sample.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /samples/src/main/res/layout/activity_rx_sample.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /samples/src/main/res/layout/activity_utility_sample.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /samples/src/main/res/layout/activity_view_sample.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 10 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /samples/src/main/res/layout/fragment_adapter_sample_grid.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 11 | 14 | 15 | 16 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /samples/src/main/res/layout/fragment_adapter_sample_list.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 11 | 14 | 15 | 16 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /samples/src/main/res/layout/fragment_adapter_sample_list_bit_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 9 | 12 | 13 | 14 | 21 | 22 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /samples/src/main/res/layout/fragment_adapter_sample_list_diff.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 11 | 14 | 15 | 16 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /samples/src/main/res/layout/fragment_adapter_sample_list_message_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 10 | 13 | 14 | 15 | 24 | 25 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /samples/src/main/res/layout/fragment_adapter_sample_list_number_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 9 | 12 | 13 | 14 | 21 | 22 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /samples/src/main/res/layout/fragment_adapter_sample_pager.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 9 | 12 | 13 | 14 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /samples/src/main/res/layout/fragment_adapter_sample_pager_bit_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 9 | 12 | 13 | 14 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /samples/src/main/res/layout/fragment_adapter_sample_pager_message_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 10 | 13 | 14 | 15 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /samples/src/main/res/layout/fragment_adapter_sample_pager_number_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 9 | 12 | 13 | 14 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /samples/src/main/res/layout/fragment_arch_sample.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 11 | 14 | 15 | 16 | 24 | 25 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /samples/src/main/res/layout/fragment_media_sample.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 10 | 13 | 14 | 15 | 19 | 20 | 25 | 26 |