diff --git a/app/build.gradle b/app/build.gradle
index e31ed1f..2d29051 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -4,7 +4,7 @@ android {
compileSdkVersion 28
defaultConfig {
applicationId "com.example.negar.testone"
- minSdkVersion 15
+ minSdkVersion 16
targetSdkVersion 28
versionCode 1
versionName "1.0"
diff --git a/app/src/main/java/com/Vasl/Library/Android/LocaleHelper.java b/app/src/main/java/com/Vasl/Library/Android/LocaleHelper.java
new file mode 100644
index 0000000..79a0ef2
--- /dev/null
+++ b/app/src/main/java/com/Vasl/Library/Android/LocaleHelper.java
@@ -0,0 +1,72 @@
+package com.Vasl.Library.Android;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.os.Build;
+
+import java.util.Locale;
+
+/**
+ * Created by Reza Amozadeh on 4/9/2017.
+ */
+
+public class LocaleHelper {
+
+ private static String LocalizationEN = "en";
+
+ private static String LocalizationFA = "fa";
+
+ public static void onAttach(Context context) {
+ LocaleHelper.setLocal(context);
+ }
+
+ public static void onAttach(Context context, String defaultLanguage) {
+ LocaleHelper.setLocal(context, defaultLanguage);
+ }
+
+ @SuppressWarnings("deprecation")
+ public static void setSystemLocaleLegacy(Configuration config, Locale locale) {
+ config.locale = locale;
+ }
+
+ @TargetApi(Build.VERSION_CODES.N)
+ public static void setSystemLocale(Configuration config, Locale locale) {
+ config.setLocale(locale);
+ }
+
+ public static void setLocal(Context context) {
+ setLocal(context, getLanguageSetting(context));
+ }
+
+ private static String getLanguageSetting(Context context) {
+ return LocalizationFA;
+ }
+
+ public static void setLocal(Context context, String language) {
+ Locale locale = new Locale(language);
+ Locale.setDefault(locale);
+
+ Configuration config = new Configuration();
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ setSystemLocale(config, locale);
+ } else {
+ setSystemLocaleLegacy(config, locale);
+ }
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ context.getApplicationContext().getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
+ } else {
+ context.getResources().updateConfiguration(config, context.getResources().getDisplayMetrics());
+ }
+ }
+
+ public static String getLocal() {
+ Locale localHelper = Locale.getDefault();
+ return localHelper.getLanguage();
+ }
+
+ public static Boolean isRTL() {
+ return getLocal().equals(LocalizationFA);
+ }
+
+}
diff --git a/app/src/main/java/com/Vasl/Library/Android/MainActivity.java b/app/src/main/java/com/Vasl/Library/Android/MainActivity.java
index 102541f..7f1e595 100644
--- a/app/src/main/java/com/Vasl/Library/Android/MainActivity.java
+++ b/app/src/main/java/com/Vasl/Library/Android/MainActivity.java
@@ -1,5 +1,6 @@
package com.Vasl.Library.Android;
+import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
@@ -45,6 +46,12 @@ public void run() {
}
+ @Override
+ protected void attachBaseContext(Context newBase) {
+ super.attachBaseContext(newBase);
+ LocaleHelper.onAttach(newBase);
+ }
+
private void myList() {
myCustomView.setStatus(ListStatuse.LOADING, null);
@@ -106,16 +113,16 @@ public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.action_load:
- myCustomView.setStatus(ListStatuse.LOADING, null);
+ myCustomView.setStatus(ListStatuse.LOADING);
return true;
case R.id.action_success:
- myCustomView.setStatus(ListStatuse.SUCCESS, null);
+ myCustomView.setStatus(ListStatuse.SUCCESS);
return true;
case R.id.action_failure:
- myCustomView.setStatus(ListStatuse.FAILURE, "hellooo");
+ myCustomView.setStatus(ListStatuse.FAILURE);
return true;
case R.id.action_empty:
- myCustomView.setStatus(ListStatuse.EMPTY, "no item");
+ myCustomView.setStatus(ListStatuse.EMPTY);
return true;
}
return false;
diff --git a/recyclerlibrary/build.gradle b/recyclerlibrary/build.gradle
index 195cbf2..4e8a603 100644
--- a/recyclerlibrary/build.gradle
+++ b/recyclerlibrary/build.gradle
@@ -4,7 +4,7 @@ android {
compileSdkVersion 28
defaultConfig {
- minSdkVersion 15
+ minSdkVersion 16
targetSdkVersion 28
versionCode 1
versionName "1.0"
@@ -19,21 +19,26 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
-
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
+ // SUPPORT LIBRARY
implementation 'androidx.appcompat:appcompat:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
- implementation 'com.github.bumptech.glide:glide:4.8.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.cardview:cardview:1.0.0'
- implementation 'com.wang.avi:library:2.1.3'
- testImplementation 'junit:junit:4.12'
+ // OTHERS
+ implementation 'com.github.bumptech.glide:glide:4.8.0'
+ implementation 'com.tuyenmonkey:mkloader:1.4.0'
+
+ // ANNOTATIONS
annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'
+
+ // TESTS
+ testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'
diff --git a/recyclerlibrary/src/main/java/com/Vasl/recyclerlibrary/MyCustomView.java b/recyclerlibrary/src/main/java/com/Vasl/recyclerlibrary/MyCustomView.java
index 690d935..ccc874d 100644
--- a/recyclerlibrary/src/main/java/com/Vasl/recyclerlibrary/MyCustomView.java
+++ b/recyclerlibrary/src/main/java/com/Vasl/recyclerlibrary/MyCustomView.java
@@ -5,6 +5,7 @@
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
+import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import com.Vasl.recyclerlibrary.globalEnums.ListStatuse;
@@ -16,24 +17,24 @@
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
-public class MyCustomView extends RelativeLayout implements View.OnClickListener
- , SwipeRefreshLayout.OnRefreshListener {
+public class MyCustomView extends RelativeLayout
+ implements View.OnClickListener, SwipeRefreshLayout.OnRefreshListener {
Context context;
// layout_loading
- RelativeLayout loading;
+ LinearLayout loading;
// recycler view
RecyclerView recyclerView;
// empty view
- RelativeLayout emptyHolder;
- AppCompatTextView emptyTextView;
+ LinearLayout emptyHolder;
+ AppCompatTextView emptyTextViewTitle, emptyTextViewSubTitle;
// error view
- RelativeLayout errorHolder;
- AppCompatTextView errorTextView;
+ LinearLayout errorHolder;
+ AppCompatTextView errorTextViewTitle, errorTextViewSubTitle;
Button buttonRetry;
// swipe
@@ -73,18 +74,25 @@ public void init() {
buttonRetry = view.findViewById(R.id.button_retry);
buttonRetry.setOnClickListener(this);
+ // loading-view
loading = view.findViewById(R.id.loadingHolder);
+ // recycler-view
recyclerView = view.findViewById(R.id.recyclerView);
+ // swipe-view
swipeRefreshLayout = view.findViewById(R.id.swipeHolder);
swipeRefreshLayout.setOnRefreshListener(this);
+ // empty-view
emptyHolder = view.findViewById(R.id.emptyHolder);
- emptyTextView = view.findViewById(R.id.emptyTextView);
+ emptyTextViewTitle = view.findViewById(R.id.emptyTextViewTitle);
+ emptyTextViewSubTitle = view.findViewById(R.id.emptyTextViewSubTitle);
+ //error-view
errorHolder = view.findViewById(R.id.errorHolder);
- errorTextView = view.findViewById(R.id.errorTextView);
+ errorTextViewTitle = view.findViewById(R.id.errorTextViewTitle);
+ errorTextViewSubTitle = view.findViewById(R.id.errorTextViewSubTitle);
}
@@ -96,15 +104,27 @@ private void showLoading() {
loading.setVisibility(VISIBLE);
}
- private void setErrorMsg(String msg){
- if (!PublicFunction.StringIsEmptyOrNull(msg)) {
- errorTextView.setText(msg);
+ private void setErrorTitle(@Nullable String title) {
+ if (!PublicFunction.StringIsEmptyOrNull(title)) {
+ errorTextViewTitle.setText(title);
}
}
- private void setEmtpyMsg(String msg){
- if (!PublicFunction.StringIsEmptyOrNull(msg)) {
- emptyTextView.setText(msg);
+ private void setErrorSubTitle(@Nullable String subTitle) {
+ if (!PublicFunction.StringIsEmptyOrNull(subTitle)) {
+ errorTextViewSubTitle.setText(subTitle);
+ }
+ }
+
+ private void setEmptyTitle(@Nullable String title) {
+ if (!PublicFunction.StringIsEmptyOrNull(title)) {
+ emptyTextViewTitle.setText(title);
+ }
+ }
+
+ private void setEmptySubTitle(@Nullable String subtitle) {
+ if (!PublicFunction.StringIsEmptyOrNull(subtitle)) {
+ emptyTextViewSubTitle.setText(subtitle);
}
}
@@ -144,7 +164,7 @@ private void hideError() {
errorHolder.setVisibility(GONE);
}
- public void setStatus(ListStatuse status,@Nullable String error) {
+ public void setStatus(ListStatuse status) {
switch (status) {
case LOADING:
showLoading();
@@ -165,7 +185,7 @@ public void setStatus(ListStatuse status,@Nullable String error) {
hideEmptyView();
hideRecyclerView();
hideSwipe();
- setErrorMsg(error);
+ setErrorTitle(null);
showError();
break;
case EMPTY:
@@ -173,7 +193,7 @@ public void setStatus(ListStatuse status,@Nullable String error) {
hideRecyclerView();
hideSwipe();
hideError();
- setEmtpyMsg(error);
+ setEmptyTitle(null);
showEmptyView();
break;
case UNDEFINE:
@@ -193,6 +213,54 @@ public void setStatus(ListStatuse status,@Nullable String error) {
}
}
+ public void setStatus(ListStatuse status, @Nullable String title) {
+ switch (status) {
+ case LOADING:
+ showLoading();
+ hideEmptyView();
+ hideRecyclerView();
+ hideSwipe();
+ hideError();
+ break;
+ case SUCCESS:
+ hideLoading();
+ hideEmptyView();
+ showRecyclerView();
+ hideSwipe();
+ hideError();
+ break;
+ case FAILURE:
+ hideLoading();
+ hideEmptyView();
+ hideRecyclerView();
+ hideSwipe();
+ setErrorTitle(title);
+ showError();
+ break;
+ case EMPTY:
+ hideLoading();
+ hideRecyclerView();
+ hideSwipe();
+ hideError();
+ setEmptyTitle(title);
+ showEmptyView();
+ break;
+ case UNDEFINE:
+ hideLoading();
+ hideEmptyView();
+ hideRecyclerView();
+ hideSwipe();
+ showError();
+ break;
+ default:
+ hideLoading();
+ hideEmptyView();
+ hideRecyclerView();
+ hideSwipe();
+ showError();
+ break;
+ }
+ }
@Override
public void onRefresh() {
diff --git a/recyclerlibrary/src/main/java/com/Vasl/recyclerlibrary/customViews/CustomImageView.java b/recyclerlibrary/src/main/java/com/Vasl/recyclerlibrary/customViews/CustomImageView.java
index ae4cae3..5fe81f9 100644
--- a/recyclerlibrary/src/main/java/com/Vasl/recyclerlibrary/customViews/CustomImageView.java
+++ b/recyclerlibrary/src/main/java/com/Vasl/recyclerlibrary/customViews/CustomImageView.java
@@ -2,15 +2,18 @@
import android.content.Context;
import android.content.res.TypedArray;
-import androidx.appcompat.widget.AppCompatImageView;
import android.util.AttributeSet;
import com.Vasl.recyclerlibrary.R;
+import androidx.appcompat.widget.AppCompatImageView;
+
public class CustomImageView extends AppCompatImageView {
- boolean isCircle;
- String gravity;
+ private boolean isCircle;
+
+ private String gravity;
+
private Context context;
public CustomImageView(Context context) {
@@ -19,6 +22,13 @@ public CustomImageView(Context context) {
init();
}
+ public CustomImageView(Context context, boolean isCircle) {
+ super(context);
+ this.context = context;
+ this.isCircle = isCircle;
+ init();
+ }
+
public CustomImageView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
diff --git a/recyclerlibrary/src/main/java/com/Vasl/recyclerlibrary/customViews/CustomLoading.java b/recyclerlibrary/src/main/java/com/Vasl/recyclerlibrary/customViews/CustomLoading.java
deleted file mode 100644
index 637fe7c..0000000
--- a/recyclerlibrary/src/main/java/com/Vasl/recyclerlibrary/customViews/CustomLoading.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.Vasl.recyclerlibrary.customViews;
-
-import android.content.Context;
-import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
-import android.util.AttributeSet;
-
-import com.wang.avi.AVLoadingIndicatorView;
-
-public class CustomLoading extends SwipeRefreshLayout {
-
-
- private Context context;
- private AVLoadingIndicatorView av;
-
- public CustomLoading(Context context) {
- super(context);
- this.context = context;
- }
-
- public CustomLoading(Context context, AttributeSet attrs) {
- super(context, attrs);
- this.context = context;
- init();
- }
-
- public void init() {
- av = new AVLoadingIndicatorView(getContext());
- av.setIndicator("LineSpinFadeLoaderIndicator");
-
-
- }
-}
diff --git a/recyclerlibrary/src/main/res/drawable/empty_256.png b/recyclerlibrary/src/main/res/drawable/empty_256.png
new file mode 100644
index 0000000..f301379
Binary files /dev/null and b/recyclerlibrary/src/main/res/drawable/empty_256.png differ
diff --git a/recyclerlibrary/src/main/res/drawable/no_wifi_256.png b/recyclerlibrary/src/main/res/drawable/no_wifi_256.png
new file mode 100644
index 0000000..730be60
Binary files /dev/null and b/recyclerlibrary/src/main/res/drawable/no_wifi_256.png differ
diff --git a/recyclerlibrary/src/main/res/drawable/retry_button_background.xml b/recyclerlibrary/src/main/res/drawable/retry_button_background.xml
index 3980481..8a4f67e 100644
--- a/recyclerlibrary/src/main/res/drawable/retry_button_background.xml
+++ b/recyclerlibrary/src/main/res/drawable/retry_button_background.xml
@@ -2,12 +2,12 @@
-
+
+ android:startColor="#3e96f2" />
\ No newline at end of file
diff --git a/recyclerlibrary/src/main/res/font/app_font.xml b/recyclerlibrary/src/main/res/font/app_font.xml
new file mode 100644
index 0000000..dbdea28
--- /dev/null
+++ b/recyclerlibrary/src/main/res/font/app_font.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/recyclerlibrary/src/main/res/font/iran_sans_light.ttf b/recyclerlibrary/src/main/res/font/iran_sans_light.ttf
new file mode 100644
index 0000000..9ec3d9c
Binary files /dev/null and b/recyclerlibrary/src/main/res/font/iran_sans_light.ttf differ
diff --git a/recyclerlibrary/src/main/res/layout/layout_empty.xml b/recyclerlibrary/src/main/res/layout/layout_empty.xml
index 6805d81..1bce123 100644
--- a/recyclerlibrary/src/main/res/layout/layout_empty.xml
+++ b/recyclerlibrary/src/main/res/layout/layout_empty.xml
@@ -1,26 +1,30 @@
-
+ android:gravity="center"
+ android:orientation="vertical"
+ android:visibility="gone">
+ android:layout_width="150dp"
+ android:layout_height="150dp"
+ android:src="@drawable/empty_256" />
+ android:text="@string/Oops" />
-
\ No newline at end of file
+
+
+
\ No newline at end of file
diff --git a/recyclerlibrary/src/main/res/layout/layout_error.xml b/recyclerlibrary/src/main/res/layout/layout_error.xml
index 9397ddd..00471c3 100644
--- a/recyclerlibrary/src/main/res/layout/layout_error.xml
+++ b/recyclerlibrary/src/main/res/layout/layout_error.xml
@@ -1,12 +1,11 @@
-
+ android:visibility="gone">
-
+
-
+
-
+
+
+
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/recyclerlibrary/src/main/res/layout/layout_loading.xml b/recyclerlibrary/src/main/res/layout/layout_loading.xml
index 325195e..dd3e8ba 100644
--- a/recyclerlibrary/src/main/res/layout/layout_loading.xml
+++ b/recyclerlibrary/src/main/res/layout/layout_loading.xml
@@ -1,29 +1,31 @@
-
-
+
+
+ android:text="@string/loading_title" />
+ android:text="@string/loading_sub_title" />
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/recyclerlibrary/src/main/res/layout/layout_my_custom_view.xml b/recyclerlibrary/src/main/res/layout/layout_my_custom_view.xml
index c20a34e..35f2232 100644
--- a/recyclerlibrary/src/main/res/layout/layout_my_custom_view.xml
+++ b/recyclerlibrary/src/main/res/layout/layout_my_custom_view.xml
@@ -1,6 +1,5 @@
-
@@ -20,7 +19,7 @@
-
+
diff --git a/recyclerlibrary/src/main/res/mipmap-hdpi/jp_noitem.png b/recyclerlibrary/src/main/res/mipmap-hdpi/jp_noitem.png
deleted file mode 100644
index c98321d..0000000
Binary files a/recyclerlibrary/src/main/res/mipmap-hdpi/jp_noitem.png and /dev/null differ
diff --git a/recyclerlibrary/src/main/res/mipmap-mdpi/jp_noitem.png b/recyclerlibrary/src/main/res/mipmap-mdpi/jp_noitem.png
deleted file mode 100644
index 5139ac1..0000000
Binary files a/recyclerlibrary/src/main/res/mipmap-mdpi/jp_noitem.png and /dev/null differ
diff --git a/recyclerlibrary/src/main/res/mipmap-xhdpi/jp_noitem.png b/recyclerlibrary/src/main/res/mipmap-xhdpi/jp_noitem.png
deleted file mode 100644
index 5139ac1..0000000
Binary files a/recyclerlibrary/src/main/res/mipmap-xhdpi/jp_noitem.png and /dev/null differ
diff --git a/recyclerlibrary/src/main/res/mipmap-xxhdpi/jp_noitem.png b/recyclerlibrary/src/main/res/mipmap-xxhdpi/jp_noitem.png
deleted file mode 100644
index 9bf9bf1..0000000
Binary files a/recyclerlibrary/src/main/res/mipmap-xxhdpi/jp_noitem.png and /dev/null differ
diff --git a/recyclerlibrary/src/main/res/mipmap-xxxhdpi/jp_noitem.png b/recyclerlibrary/src/main/res/mipmap-xxxhdpi/jp_noitem.png
deleted file mode 100644
index 788a818..0000000
Binary files a/recyclerlibrary/src/main/res/mipmap-xxxhdpi/jp_noitem.png and /dev/null differ
diff --git a/recyclerlibrary/src/main/res/values-fa/strings.xml b/recyclerlibrary/src/main/res/values-fa/strings.xml
index cb3435a..5180e03 100644
--- a/recyclerlibrary/src/main/res/values-fa/strings.xml
+++ b/recyclerlibrary/src/main/res/values-fa/strings.xml
@@ -1,7 +1,15 @@
+
recyclerLibrary
فیلدی برای نمایش وجود ندارد
اتفاق بدی افتاده
تلاش مجدد
- Loading ...
+ بارگذاری
+ عجب!
+ لیست مورد نظر شما خالی است
+ خطا!
+ اشکالی پیش آمده، لطفا مجدد تلاش کنید
+ بارگذاری
+ لطفا چند لحظه صبر کنید
+
diff --git a/recyclerlibrary/src/main/res/values/strings.xml b/recyclerlibrary/src/main/res/values/strings.xml
index d7e002e..2405332 100644
--- a/recyclerlibrary/src/main/res/values/strings.xml
+++ b/recyclerlibrary/src/main/res/values/strings.xml
@@ -4,4 +4,10 @@
some thing bad happened! ;)
Retry
Loading ...
+ Oops!
+ Your list is empty, \n so there is nothing to show here.
+ UH OH!
+ Something went wrong, \n please try again
+ Loading
+ Please wait until request complete
diff --git a/recyclerlibrary/src/main/res/values/styles.xml b/recyclerlibrary/src/main/res/values/styles.xml
index fd3baa5..d2bec88 100644
--- a/recyclerlibrary/src/main/res/values/styles.xml
+++ b/recyclerlibrary/src/main/res/values/styles.xml
@@ -15,11 +15,31 @@
- @color/colorPrimary
-
+
+
+
+
+