18 | */
19 | public static > void execute(T task) {
20 | execute(task, (P[]) null);
21 | }
22 |
23 | @SuppressLint("NewApi")
24 | public static
> void execute(T task, P... params) {
25 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
26 | task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
27 | } else {
28 | task.execute(params);
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/commons/src/main/res/layout/labeled_textview.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
18 |
19 |
27 |
28 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/util/DecimalFormatUtil.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.util;
2 |
3 | import java.text.DecimalFormat;
4 | import java.text.DecimalFormatSymbols;
5 | import java.text.NumberFormat;
6 | import java.util.Locale;
7 |
8 | /**
9 | * Created by Rcsk on 2014.06.16..
10 | */
11 | public class DecimalFormatUtil {
12 |
13 | /**
14 | * Returns a thousans separated decimar formatter.
15 | *
16 | * @return
17 | */
18 | public static DecimalFormat getThousandSeperatedDecimalFormat() {
19 | DecimalFormat df = (DecimalFormat) NumberFormat.getInstance(Locale.US);
20 | DecimalFormatSymbols symbols = df.getDecimalFormatSymbols();
21 | symbols.setGroupingSeparator(' ');
22 | df.setDecimalFormatSymbols(symbols);
23 | return df;
24 | }
25 |
26 |
27 | /**
28 | *
29 | * @param value e.g. 1.199999
30 | * @return 1.2
31 | */
32 | public static String formatDouble(double value) {
33 | return new DecimalFormat("#.##").format(value);
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/app/src/main/java/com/richardradics/cleanaa/mvp/view/model/MainListViewModel.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.cleanaa.mvp.view.model;
2 |
3 | /**
4 | * Created by radicsrichard on 15. 05. 13..
5 | */
6 | public class MainListViewModel {
7 |
8 | private Long id;
9 | private String imageUrl;
10 | private String title;
11 |
12 | public MainListViewModel() {
13 |
14 | }
15 |
16 | public MainListViewModel(Long id, String imageUrl, String title) {
17 | this.id = id;
18 | this.imageUrl = imageUrl;
19 | this.title = title;
20 | }
21 |
22 | public Long getId() {
23 | return id;
24 | }
25 |
26 | public void setId(Long id) {
27 | this.id = id;
28 | }
29 |
30 | public String getImageUrl() {
31 | return imageUrl;
32 | }
33 |
34 | public void setImageUrl(String imageUrl) {
35 | this.imageUrl = imageUrl;
36 | }
37 |
38 | public String getTitle() {
39 | return title;
40 | }
41 |
42 | public void setTitle(String title) {
43 | this.title = title;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/util/RegexUtil.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.util;
2 |
3 | /**
4 | * Common regexps.
5 | *
6 | * Created by Richard Radics on 2015.02.11..
7 | */
8 | public class RegexUtil {
9 |
10 |
11 | public static final String EMAIL_PATTERN = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-\\+]+)*@" + "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$";
12 |
13 | // public static final String PASSWORD_PATTERN =
14 | // "(?=(.*[a-zA-Z]))^[0-9a-zA-Z!@#$%^&*()_+\\-=\\[\\]{};':\"\\|,.<>\\/?]{4,}$";
15 |
16 | public static final String PASSWORD_PATTERN = ".{4,}";
17 |
18 |
19 | public static final String USERNAME_PATTERN = "(?=(.*[a-zA-Z]){3})^[0-9a-zA-Z]{3,}$";
20 |
21 | public static final String ANYTHING_PATTERN = ".*";
22 |
23 | // public static final String USERNAME_LENGTH_PATTERN =
24 | // "((?=.*\d)|(?=.*[a-z])|(?=.*[a-z])|(?=.*[A-Z]).{5,20})";
25 |
26 | public static final String FULL_NAME_PATTERN = "^([ \\x{00C0}-\\x{01FF}a-zA-Z\\'\\-\\.])*$"; //
27 |
28 | public static final String PHONE_PATTERN = "^[0-9]{8,13}$";
29 |
30 |
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/util/RandomUtil.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.util;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Collections;
5 | import java.util.List;
6 |
7 | /**
8 | * Created by richardradics on 2015.02.17..
9 | */
10 | public class RandomUtil {
11 |
12 |
13 | /***
14 | * Random numbers generator.
15 | *
16 | * @param startNumber the range start number
17 | * @param endNumber the range end number
18 | * @param numberCount the count of the requested randomnumbers.
19 | * @return an array with random numbers
20 | */
21 | public static int[] getRandomNumbers(int startNumber, int endNumber, int numberCount){
22 |
23 | int[] randomNumbers = new int[numberCount];
24 |
25 | List list = new ArrayList();
26 | for(int i = startNumber; i <= endNumber; i++) list.add(i);
27 | Collections.shuffle(list);
28 |
29 |
30 | for(int i = 0; i< numberCount; i++){
31 | randomNumbers[i] = list.get(i);
32 | }
33 |
34 |
35 | return randomNumbers;
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/helper/OnClickHelper.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.helper;
2 |
3 | import org.apache.commons.lang3.time.DateUtils;
4 |
5 | import java.util.Date;
6 |
7 | /**
8 | * Created by Richard Radics on 2015.02.11..
9 | */
10 | public class OnClickHelper {
11 | private static Date occupiedUntil = null;
12 |
13 | public static int DEFAULT_WAIT_MS = 600;
14 |
15 | /**
16 | * Tries to occupy the onclick enabler.
17 | * @param waitMs the time interval to occupy
18 | * @return if noone occupied it, returns true, else false
19 | */
20 | public static boolean occupy(int waitMs){
21 | if(occupiedUntil != null && occupiedUntil.after(new Date())){
22 | return false;
23 | }
24 | occupiedUntil = DateUtils.addMilliseconds(new Date(), waitMs);
25 | return true;
26 | }
27 |
28 | /**
29 | * Tries to occupy the onclick enabler for the default time limit
30 | * @return if noone occupied it, returns true, else false
31 | */
32 | public static boolean occupy(){
33 | return occupy(DEFAULT_WAIT_MS);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/commons/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
8 |
15 |
16 |
17 |
22 |
23 |
24 |
25 |
26 |
27 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/widget/floatingwidgets/ChoiceableItemPrinter.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.widget.floatingwidgets;
2 |
3 | import com.marvinlabs.widget.floatinglabel.itempicker.ItemPrinter;
4 |
5 | import java.util.Collection;
6 |
7 | /**
8 | * Created by Richard Radics on 2015.02.10..
9 | */
10 | public class ChoiceableItemPrinter implements ItemPrinter {
11 |
12 |
13 | @Override
14 | public String print(Choiceable choiceable) {
15 | return choiceable.getTitleText() == null ? "" : choiceable.getTitleText();
16 | }
17 |
18 | @Override
19 | public String printCollection(Collection choiceables) {
20 | if (choiceables.size() == 0) return "";
21 |
22 | StringBuilder sb = new StringBuilder();
23 | boolean prependSeparator = false;
24 | for (Choiceable item : choiceables) {
25 | if (prependSeparator) {
26 | sb.append(", ");
27 | } else {
28 | prependSeparator = true;
29 | }
30 |
31 | sb.append(print(item));
32 | }
33 |
34 | return sb.toString();
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/core/src/main/java/com/richardradics/core/navigation/Navigator.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.core.navigation;
2 |
3 | import android.content.Context;
4 |
5 | import com.richardradics.core.app.BaseActivity;
6 |
7 | import org.androidannotations.annotations.EBean;
8 | import org.androidannotations.annotations.RootContext;
9 |
10 |
11 | /**
12 | * Created by radicsrichard on 15. 03. 28..
13 | */
14 | @EBean(scope = EBean.Scope.Singleton)
15 | public class Navigator {
16 |
17 | @RootContext
18 | Context context;
19 |
20 |
21 | private BaseActivity currentActivityOnScreen;
22 |
23 |
24 | public BaseActivity getCurrentActivityOnScreen() {
25 | return currentActivityOnScreen;
26 | }
27 |
28 | public void setCurrentActivityOnScreen(BaseActivity currentActivityOnScreen) {
29 | this.currentActivityOnScreen = currentActivityOnScreen;
30 | }
31 |
32 | public static void navigateUp(BaseActivity activity) {
33 | activity.finish();
34 | }
35 |
36 | public boolean isInForeground(){
37 | if(currentActivityOnScreen != null){
38 | return Boolean.TRUE;
39 | }else{
40 | return Boolean.FALSE;
41 | }
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/commons/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 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/security/HashGenerator.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.security;
2 |
3 | import java.security.MessageDigest;
4 | import java.security.NoSuchAlgorithmException;
5 |
6 | /**
7 | * Created by Richard Radics on 2015.02.11..
8 | */
9 | public class HashGenerator {
10 |
11 |
12 | /**
13 | * Generates hash from the specified string.
14 | * @param s
15 | * @return
16 | */
17 | public static final String generateHash(final String s) {
18 | try {
19 | // Create MD5 Hash
20 | MessageDigest digest = java.security.MessageDigest
21 | .getInstance("MD5");
22 | digest.update(s.getBytes());
23 | byte messageDigest[] = digest.digest();
24 |
25 | // Create Hex String
26 | StringBuffer hexString = new StringBuffer();
27 | for (int i = 0; i < messageDigest.length; i++) {
28 | String h = Integer.toHexString(0xFF & messageDigest[i]);
29 | while (h.length() < 2)
30 | h = "0" + h;
31 | hexString.append(h);
32 | }
33 | return hexString.toString();
34 |
35 | } catch (NoSuchAlgorithmException e) {
36 | e.printStackTrace();
37 | }
38 | return "";
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/widget/echeckbox/EnhancedToggleButton.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.widget.echeckbox;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.widget.CompoundButton;
6 | import android.widget.ToggleButton;
7 |
8 | public class EnhancedToggleButton extends ToggleButton implements ProgrammaticallyCheckable {
9 | private CompoundButton.OnCheckedChangeListener mListener = null;
10 | public EnhancedToggleButton(Context context, AttributeSet attrs, int defStyle) {
11 | super(context, attrs, defStyle);
12 | }
13 |
14 | public EnhancedToggleButton(Context context, AttributeSet attrs) {
15 | super(context, attrs);
16 | }
17 |
18 | public EnhancedToggleButton(Context context) {
19 | super(context);
20 | }
21 |
22 | @Override
23 | public void setOnCheckedChangeListener(
24 | CompoundButton.OnCheckedChangeListener listener){
25 | if(this.mListener == null) {this.mListener = listener;}
26 | super.setOnCheckedChangeListener(listener);
27 | }
28 |
29 | @Override
30 | public void setCheckedProgrammatically(boolean checked){
31 | super.setOnCheckedChangeListener(null);
32 | super.setChecked(checked);
33 | super.setOnCheckedChangeListener(mListener);
34 | }
35 | }
--------------------------------------------------------------------------------
/commons/src/main/res/layout/grouped_checkbox_list.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
20 |
21 |
26 |
27 |
28 |
29 |
33 |
34 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/widget/floatingwidgets/ChoiceableExpandPickerWidgetListener.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.widget.floatingwidgets;
2 |
3 | import android.view.View;
4 | import android.widget.TextView;
5 |
6 | import com.richardradics.commons.animations.ExpandAnimation;
7 |
8 | /**
9 | * Created by Richard Radics on 2015.02.12..
10 | */
11 | public class ChoiceableExpandPickerWidgetListener implements FloatingLabelItemPickerWithSetSelectedItems.OnWidgetEventListener{
12 |
13 | private boolean isExpanded = false;
14 |
15 | private View viewToExpand;
16 |
17 | public ChoiceableExpandPickerWidgetListener(View viewToExpand){
18 | this.viewToExpand = viewToExpand;
19 | }
20 |
21 |
22 | @Override
23 | public void onShowItemPickerDialog(FloatingLabelItemPickerWithSetSelectedItems floatingLabelItemPicker) {
24 | if (!isExpanded) {
25 | floatingLabelItemPicker.floatLabel();
26 | ExpandAnimation.expand(viewToExpand);
27 | isExpanded = true;
28 | } else {
29 | if (((TextView) floatingLabelItemPicker.getInputWidget()).getText().toString().equals("")) {
30 | floatingLabelItemPicker.anchorLabel();
31 | }
32 | ExpandAnimation.collapse(viewToExpand);
33 | isExpanded = false;
34 | }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/util/PhoneUtil.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.util;
2 |
3 | import android.content.Context;
4 | import android.provider.Settings;
5 | import android.util.DisplayMetrics;
6 |
7 | /**
8 | * Created by Richard Radics on 2015.02.12..
9 | */
10 | public class PhoneUtil {
11 |
12 | /**
13 | * Checks to see if the user has rotation enabled/disabled in their phone settings.
14 | *
15 | * @param context The current Context or Activity that this method is called from
16 | * @return true if rotation is enabled, otherwise false.
17 | */
18 | public static boolean isRotationEnabled(Context context) {
19 | return android.provider.Settings.System.getInt(context.getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, 0) == 1;
20 | }
21 |
22 | /**
23 | * Retuns device DPI.
24 | * @param c
25 | * @return
26 | */
27 | public static int deviceDPI(Context c) {
28 | return c.getResources().getDisplayMetrics().densityDpi;
29 | }
30 |
31 | /**
32 | * Retuns device resolution.
33 | * @param c
34 | * @return
35 | */
36 | public static String deviceResolution(Context c) {
37 | DisplayMetrics metrics = c.getResources().getDisplayMetrics();
38 | return String.valueOf(metrics.widthPixels) + "x" + metrics.heightPixels;
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
18 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/widget/echeckbox/EnhancedSwitch.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.widget.echeckbox;
2 |
3 | import android.annotation.TargetApi;
4 | import android.content.Context;
5 | import android.os.Build;
6 | import android.util.AttributeSet;
7 | import android.widget.CompoundButton;
8 | import android.widget.Switch;
9 |
10 | @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
11 | public class EnhancedSwitch extends Switch implements ProgrammaticallyCheckable {
12 | private CompoundButton.OnCheckedChangeListener mListener = null;
13 |
14 | public EnhancedSwitch(Context context, AttributeSet attrs, int defStyle) {
15 | super(context, attrs, defStyle);
16 | }
17 |
18 | public EnhancedSwitch(Context context, AttributeSet attrs) {
19 | super(context, attrs);
20 | }
21 |
22 | public EnhancedSwitch(Context context) {
23 | super(context);
24 | }
25 |
26 | @Override
27 | public void setOnCheckedChangeListener(
28 | CompoundButton.OnCheckedChangeListener listener){
29 | if(this.mListener == null) {this.mListener = listener;}
30 | super.setOnCheckedChangeListener(listener);
31 | }
32 |
33 | @Override
34 | public void setCheckedProgrammatically(boolean checked){
35 | super.setOnCheckedChangeListener(null);
36 | super.setChecked(checked);
37 | super.setOnCheckedChangeListener(mListener);
38 | }
39 | }
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/test/TestHelper.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.test;
2 |
3 | import android.util.Log;
4 |
5 | import org.apache.commons.io.IOUtils;
6 |
7 | import java.io.IOException;
8 | import java.lang.reflect.Field;
9 | import java.lang.reflect.Modifier;
10 | import java.util.List;
11 |
12 | /**
13 | * Created by radicsrichard on 15. 05. 18..
14 | */
15 | public class TestHelper {
16 |
17 | public static void setFinalStatic(Field field, Object newValue) throws Exception {
18 | field.setAccessible(true);
19 |
20 | // remove final modifier from field
21 | Field modifiersField = Field.class.getDeclaredField("modifiers");
22 | modifiersField.setAccessible(true);
23 | modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
24 |
25 | field.set(null, newValue);
26 | }
27 |
28 | public static String getStringFromResource(String resourceName){
29 | String result = "";
30 | ClassLoader classLoader = TestHelper.class.getClassLoader();
31 | try {
32 | result = IOUtils.toString(classLoader.getResourceAsStream(resourceName), "UTF-8");
33 | } catch (IOException e) {
34 | e.printStackTrace();
35 | }
36 |
37 | return result;
38 | }
39 |
40 | public static void printCollection(List collection){
41 | Log.i("Data", String.valueOf(collection));
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/util/ColorUtil.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.util;
2 |
3 | import android.graphics.Color;
4 |
5 | import java.util.Random;
6 |
7 | /**
8 | * Created by Richard Radics on 2014.12.11..
9 | */
10 | public class ColorUtil {
11 |
12 | private static Random randomGenerator = new Random();
13 |
14 |
15 | /**
16 | * Gets a random darker color.
17 | * @return
18 | */
19 | public static int getRandomDarkColor(){
20 | int randColor = getRandomColor();
21 | return darker(randColor, 0.75f);
22 | }
23 |
24 |
25 | /**
26 | * Retuns a darker color from a specified color by the factor.
27 | * @param color
28 | * @param factor
29 | * @return
30 | */
31 | public static int darker (int color, float factor) {
32 | int a = Color.alpha( color );
33 | int r = Color.red( color );
34 | int g = Color.green( color );
35 | int b = Color.blue( color );
36 |
37 | return Color.argb( a,
38 | Math.max( (int)(r * factor), 0 ),
39 | Math.max( (int)(g * factor), 0 ),
40 | Math.max( (int)(b * factor), 0 ) );
41 | }
42 |
43 |
44 | /**
45 | * Returns a random color.
46 | * @return
47 | */
48 | public static int getRandomColor(){
49 | return Color.rgb(randomGenerator.nextInt(255), randomGenerator.nextInt(255), randomGenerator.nextInt(255));
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/core/src/main/java/com/richardradics/core/retrofit/BaseRetryHandler.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.core.retrofit;
2 |
3 | import com.richardradics.core.error.NetworkErrorHandler;
4 | import com.richardradics.core.navigation.Navigator;
5 |
6 | import org.androidannotations.annotations.Bean;
7 | import org.androidannotations.annotations.EBean;
8 |
9 | import hugo.weaving.DebugLog;
10 |
11 | /**
12 | * Created by radicsrichard on 15. 05. 16..
13 | */
14 | @EBean
15 | public class BaseRetryHandler {
16 |
17 | @Bean
18 | protected NetworkErrorHandler networkErrorHandler;
19 |
20 | @Bean
21 | protected Navigator navigator;
22 |
23 | public int DEFAULT_RETRY_COUNT = 2;
24 | public int RETRY_401_UNAUTHORIZED = 3;
25 | public int RETRY_400_BADREQUEST = 3;
26 | public int RETRY_403_FORBIDDEN = 3;
27 | public int RETRY_404_NOTFOUND = 3;
28 | public int RETRY_500_ISE = 3;
29 |
30 |
31 | @DebugLog
32 | public void on500() {
33 |
34 | }
35 |
36 | @DebugLog
37 | public void on401() {
38 |
39 | }
40 |
41 | @DebugLog
42 | public void on400() {
43 |
44 | }
45 |
46 |
47 | @DebugLog
48 | public void on404() {
49 |
50 | }
51 |
52 | @DebugLog
53 | public void on403() {
54 |
55 | }
56 |
57 | public void onNoInternet() {
58 | if (navigator.isInForeground()) {
59 | navigator.getCurrentActivityOnScreen().onNoConnectivityError();
60 | }
61 | networkErrorHandler.handlerError(new NoConnectivityException("Nincs internet!"));
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
14 |
15 |
16 |
18 |
19 |
24 |
25 |
32 |
33 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/listeners/OnItemSelectedListenerWrapper.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.listeners;
2 |
3 | import android.util.Log;
4 | import android.view.View;
5 | import android.widget.AdapterView;
6 |
7 | /**
8 | * Created by Richard Radics on 2015.02.11..
9 | */
10 | public class OnItemSelectedListenerWrapper implements AdapterView.OnItemSelectedListener {
11 |
12 | private int lastPosition;
13 | private AdapterView.OnItemSelectedListener listener;
14 |
15 | private boolean isFirstStart = true;
16 |
17 |
18 | public OnItemSelectedListenerWrapper(AdapterView.OnItemSelectedListener listener) {
19 | lastPosition = 0;
20 | this.listener = listener;
21 | }
22 |
23 | @Override
24 | public void onItemSelected(AdapterView> aParentView, View aView, int aPosition, long anId) {
25 | if (!isFirstStart) {
26 | if (lastPosition == aPosition) {
27 | Log.d("ItemSelectedWrapper", "Ignoring onItemSelected for same position: " + aPosition);
28 | } else {//
29 | Log.d("ItemSelectedWrapper", "Passing on onItemSelected for different position: " + aPosition);
30 | listener.onItemSelected(aParentView, aView, aPosition, anId);
31 | }
32 | lastPosition = aPosition;
33 | } else {
34 | isFirstStart = false;
35 | }
36 | }
37 |
38 | @Override
39 | public void onNothingSelected(AdapterView> aParentView) {
40 | listener.onNothingSelected(aParentView);
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/util/ListViewUtil.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.util;
2 |
3 |
4 | import android.util.Log;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.ListAdapter;
8 | import android.widget.ListView;
9 |
10 | /**
11 | * Created by Richard Radics on 2015.02.09..
12 | */
13 | public class ListViewUtil {
14 |
15 |
16 | /**** Method for Setting the Height of the ListView dynamically.
17 | **** Hack to fix the issue of not showing all the items of the ListView
18 | **** when placed inside a ScrollView ****/
19 | public static void setListViewHeightBasedOnChildren(ListView listView) {
20 | ListAdapter mAdapter = listView.getAdapter();
21 |
22 | int totalHeight = 0;
23 |
24 | for (int i = 0; i < mAdapter.getCount(); i++) {
25 | View mView = mAdapter.getView(i, null, listView);
26 |
27 | mView.measure(
28 | View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
29 |
30 | View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
31 |
32 | totalHeight += mView.getMeasuredHeight();
33 | Log.w("HEIGHT" + i, String.valueOf(totalHeight));
34 |
35 | }
36 |
37 | ViewGroup.LayoutParams params = listView.getLayoutParams();
38 | params.height = totalHeight
39 | + (listView.getDividerHeight() * (mAdapter.getCount() - 1));
40 | listView.setLayoutParams(params);
41 | listView.requestLayout();
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/util/SDCardUtil.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.util;
2 |
3 | import android.os.Environment;
4 | import android.os.StatFs;
5 |
6 | /**
7 | * Created by Richard Radics on 2015.02.11..
8 | */
9 | public class SDCardUtil {
10 |
11 | /**
12 | * Returns the SD card is available.
13 | * @return
14 | */
15 | public static Boolean checkAvailable() {
16 | String state = Environment.getExternalStorageState();
17 |
18 | if (Environment.MEDIA_MOUNTED.equals(state)) {
19 | return true;
20 | } else {
21 | return false;
22 | }
23 | }
24 |
25 | /**
26 | * Checks the SD card is readonly.
27 | * @return
28 | */
29 | public static Boolean checkIsReadOnly() {
30 | String state = Environment.getExternalStorageState();
31 | if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
32 | return true;
33 | } else {
34 | return false;
35 | }
36 | }
37 |
38 | /**
39 | * Returns the available space in megabytes.
40 | * @return
41 | */
42 | public static int getAvailableSpaceInMegaBytes() {
43 | int availableSpace = 0;
44 |
45 | try {
46 | StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());
47 | availableSpace = stat.getAvailableBlocks() * stat.getBlockSize() / 1048576;
48 | } catch (Exception e) {
49 | e.printStackTrace();
50 | }
51 | return availableSpace;
52 | }
53 |
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/commons/src/main/res/layout/grouped_checkbox.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
15 |
16 |
25 |
26 |
37 |
38 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/widget/FixedHeightListView.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.widget;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.View;
6 | import android.widget.ArrayAdapter;
7 | import android.widget.LinearLayout;
8 |
9 | /**
10 | * Project: commons
11 | * Package: com.richardradics.commons.widget
12 | * Created by richardradics on 2015.02.24..
13 | */
14 | public class FixedHeightListView extends LinearLayout implements View.OnClickListener {
15 |
16 | private ArrayAdapter mList;
17 | private View.OnClickListener mListener;
18 | private View view;
19 |
20 | public FixedHeightListView(Context context) {
21 | super(context);
22 | }
23 |
24 | public FixedHeightListView(Context context, AttributeSet attrs) {
25 | super(context, attrs);
26 | }
27 |
28 | public FixedHeightListView(Context context, AttributeSet attrs, int defStyle) {
29 | super(context, attrs, defStyle);
30 | }
31 |
32 | public void setAdapter(ArrayAdapter list) {
33 | this.mList = list;
34 | setOrientation(VERTICAL);
35 |
36 | if (mList != null) {
37 | for (int i = 0; i < mList.getCount(); i++) {
38 | view = mList.getView(i, null, null);
39 | this.addView(view);
40 | }
41 | }
42 | }
43 |
44 | public void setListener(View.OnClickListener listener) {
45 | this.mListener = listener;
46 | }
47 |
48 | @Override
49 | public void onClick(View v) {
50 | }
51 |
52 |
53 | }
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | - #2196F3
5 | - #1565C0
6 | - #F50057
7 | - #FFFF00
8 |
9 |
10 | - #4CAF50
11 | - #F4FF81
12 | - #FFEB3B
13 |
14 | - #FFEB3B
15 |
16 |
17 | - @color/material_blue_500
18 | - @color/material_blue_800
19 |
20 | - #58000000
21 | - #FFF
22 |
23 | @color/material_blue_500
24 | @color/material_green_500
25 | @color/material_yellow_500
26 | @color/material_blue_800
27 | #FFF
28 | @color/material_blue_500
29 | #fff
30 | #333333
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/java/com/richardradics/cleanaa/util/RecyclerItemClickListener.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.cleanaa.util;
2 |
3 | import android.content.Context;
4 | import android.support.v7.widget.RecyclerView;
5 | import android.view.GestureDetector;
6 | import android.view.MotionEvent;
7 | import android.view.View;
8 |
9 |
10 | /**
11 | * Created by radicsrichard on 15. 05. 13..
12 | */
13 | public class RecyclerItemClickListener implements RecyclerView.OnItemTouchListener {
14 | private OnItemClickListener mListener;
15 |
16 | public interface OnItemClickListener {
17 | public void onItemClick(View view, int position);
18 | }
19 |
20 | GestureDetector mGestureDetector;
21 |
22 | public RecyclerItemClickListener(Context context, OnItemClickListener listener) {
23 | mListener = listener;
24 | mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
25 | @Override
26 | public boolean onSingleTapUp(MotionEvent e) {
27 | return true;
28 | }
29 | });
30 | }
31 |
32 | @Override
33 | public boolean onInterceptTouchEvent(RecyclerView view, MotionEvent e) {
34 | View childView = view.findChildViewUnder(e.getX(), e.getY());
35 | if (childView != null && mListener != null && mGestureDetector.onTouchEvent(e)) {
36 | mListener.onItemClick(childView, view.getChildPosition(childView));
37 | }
38 | return false;
39 | }
40 |
41 | @Override
42 | public void onTouchEvent(RecyclerView view, MotionEvent motionEvent) {
43 | }
44 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/richardradics/cleanaa/interactor/GetCitiesImp.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.cleanaa.interactor;
2 |
3 | import com.richardradics.cleanaa.domain.City;
4 | import com.richardradics.cleanaa.exception.GetCitiesException;
5 | import com.richardradics.cleanaa.repository.api.model.openweatherwrapper.OpenWeatherWrapper;
6 | import com.richardradics.cleanaa.repository.api.model.openweatherwrapper.WeatherItem;
7 |
8 | import org.androidannotations.annotations.Background;
9 | import org.androidannotations.annotations.EBean;
10 | import org.androidannotations.annotations.UiThread;
11 |
12 | import java.util.List;
13 |
14 | import hugo.weaving.DebugLog;
15 |
16 | /**
17 | * Created by radicsrichard on 15. 05. 13..
18 | */
19 | @EBean
20 | public class GetCitiesImp extends BaseInteractor implements GetCities {
21 |
22 | private Callback callback;
23 |
24 | @Override
25 | @Background
26 | @DebugLog
27 | public void getCities(Double latitude, Double longitude, Integer count, Callback callback) {
28 | this.callback = callback;
29 | try {
30 | List cityList = cleanRepository.getCities(latitude, longitude, count);
31 | onItemsLoaded(cityList);
32 | } catch (GetCitiesException getCitiesException) {
33 | onError(getCitiesException);
34 | }
35 | }
36 |
37 | @UiThread
38 | @DebugLog
39 | public void onItemsLoaded(List cityList) {
40 | callback.onCitiesoaded(cityList);
41 | }
42 |
43 | @UiThread
44 | public void onError(Exception e) {
45 | callback.onError(e);
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/app/src/main/java/com/richardradics/cleanaa/repository/api/OpenWeatherResponseMapper.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.cleanaa.repository.api;
2 |
3 | import com.richardradics.cleanaa.app.CleanErrorHandler;
4 | import com.richardradics.cleanaa.domain.City;
5 | import com.richardradics.cleanaa.repository.api.mapper.WeatherResponseMapper;
6 | import com.richardradics.cleanaa.repository.api.model.openweatherwrapper.OpenWeatherWrapper;
7 | import com.richardradics.cleanaa.repository.api.model.openweatherwrapper.WeatherItem;
8 |
9 | import org.androidannotations.annotations.Bean;
10 | import org.androidannotations.annotations.EBean;
11 |
12 | import java.util.ArrayList;
13 | import java.util.List;
14 |
15 | /**
16 | * Created by radicsrichard on 15. 05. 14..
17 | */
18 | @EBean(scope = EBean.Scope.Singleton)
19 | public class OpenWeatherResponseMapper implements WeatherResponseMapper {
20 |
21 | @Bean
22 | CleanErrorHandler cleanErrorHandler;
23 |
24 | @Override
25 | public List mapResponse(OpenWeatherWrapper response) {
26 | List cityList = new ArrayList<>();
27 |
28 | for (WeatherItem weatherItem : response.getList()) {
29 | try {
30 | City w = new City();
31 | w.setId(weatherItem.getId());
32 | w.setName(weatherItem.getName());
33 | w.setCountry(weatherItem.getSys().getCountry());
34 |
35 | cityList.add(w);
36 | } catch (Exception e) {
37 | cleanErrorHandler.logExpception(e);
38 | }
39 | }
40 |
41 | return cityList;
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/util/ToastUtil.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.util;
2 |
3 | import android.content.Context;
4 | import android.widget.Toast;
5 |
6 | /**
7 | * Created by Richard Radics on 2015.02.12..
8 | */
9 | public class ToastUtil {
10 |
11 | /**
12 | * Display a toast with the given message (Length will be Toast.LENGTH_SHORT -- approx 2 sec).
13 | *
14 | * @param context The current Context or Activity that this method is called from
15 | * @param message Message to display
16 | * @return Toast object that is being displayed. Note,show() has already been called on this object.
17 | */
18 | public static Toast quickToast(Context context, String message) {
19 | return quickToast(context, message, false);
20 | }
21 |
22 | /**
23 | * Display a toast with the given message.
24 | *
25 | * @param context The current Context or Activity that this method is called from
26 | * @param message Message to display
27 | * @param longLength if true, will use Toast.LENGTH_LONG (approx 3.5 sec) instead of
28 | * @return Toast object that is being displayed. Note,show() has already been called on this object.
29 | */
30 | public static Toast quickToast(Context context, String message, boolean longLength) {
31 | final Toast toast;
32 | if (longLength) {
33 | toast = Toast.makeText(context, message, Toast.LENGTH_LONG);
34 | } else {
35 | toast = Toast.makeText(context, message, Toast.LENGTH_SHORT);
36 | }
37 | toast.show();
38 | return toast;
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/util/GridViewUtil.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.util;
2 |
3 | import android.view.View;
4 | import android.view.ViewGroup;
5 | import android.widget.GridView;
6 | import android.widget.ListAdapter;
7 |
8 | /**
9 | * Created by Richard Radics on 2014.12.11..
10 | */
11 | public class GridViewUtil {
12 |
13 | /**
14 | * Resizes the gridview.
15 | * @param gridView
16 | * @param items count
17 | * @param columns column number
18 | */
19 | public static void resizeGridView(GridView gridView, int columns) {
20 | ListAdapter listAdapter = gridView.getAdapter();
21 | if (listAdapter == null) {
22 | // pre-condition
23 | return;
24 | }
25 |
26 | int totalHeight = 0;
27 | int items = listAdapter.getCount();
28 | int rows = 0;
29 |
30 | int maxHeight = 0;
31 |
32 | for(int i = 0; i< listAdapter.getCount(); i++ ){
33 | View listItem = listAdapter.getView(i, null, gridView);
34 | listItem.measure(0, 0);
35 | totalHeight = listItem.getMeasuredHeight();
36 | if(maxHeight < totalHeight){
37 | maxHeight = totalHeight;
38 | }
39 | }
40 |
41 |
42 |
43 | float x = 1;
44 | if( items > columns ){
45 | x = items/columns;
46 | rows = (int) (x + 1);
47 | maxHeight *= rows;
48 | }
49 |
50 | ViewGroup.LayoutParams params = gridView.getLayoutParams();
51 | params.height = maxHeight;
52 | gridView.setLayoutParams(params);
53 |
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/util/HungarianCollation.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.util;
2 |
3 | import java.text.ParseException;
4 | import java.text.RuleBasedCollator;
5 |
6 | /**
7 | * Created by User on 2014.12.19..
8 | */
9 | public class HungarianCollation extends RuleBasedCollator {
10 |
11 | /**
12 | * Constructs a new instance of {@code RuleBasedCollator} using the
13 | * specified {@code rules}. (See the {@link java.text.RuleBasedCollator class description}.)
14 | *
15 | * Note that the {@code rules} are interpreted as a delta to the
16 | * default sort order. This differs
17 | * from other implementations which work with full {@code rules}
18 | * specifications and may result in different behavior.
19 | *
20 | * @param rules the collation rules.
21 | * @throws NullPointerException if {@code rules == null}.
22 | * @throws java.text.ParseException if {@code rules} contains rules with invalid collation rule
23 | * syntax.
24 | */
25 | public HungarianCollation() throws ParseException {
26 | super(hungarianRules);
27 | }
28 |
29 | /**
30 | * Hungarian Collator Rules.
31 | */
32 | public static String hungarianRules = ("&9 < a,A < á,Á < b,B < c,C < cs,Cs < d,D < dz,Dz < dzs,Dzs "
33 | + "< e,E < é,É < f,F < g,G < gy,Gy < h,H < i,I < í,Í < j,J "
34 | + "< k,K < l,L < ly,Ly < m,M < n,N < ny,Ny < o,O < ó,Ó "
35 | + "< ö,Ö < õ,Õ < p,P < q,Q < r,R < s,S < sz,Sz < t,T "
36 | + "< ty,Ty < u,U < ú,Ú < v,V < w,W < x,X < y,Y < z,Z < zs,Zs");
37 |
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/app/src/test/java/com/richardradics/cleanaa/util/AppRobolectricRunner.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.cleanaa.util;
2 |
3 |
4 | import org.junit.runners.model.InitializationError;
5 | import org.robolectric.RobolectricGradleTestRunner;
6 | import org.robolectric.annotation.Config;
7 | import org.robolectric.manifest.AndroidManifest;
8 | import org.robolectric.res.FileFsFile;
9 | import org.robolectric.res.FsFile;
10 |
11 | /**
12 | * Created by radicsrichard on 15. 05. 15..
13 | */
14 | public class AppRobolectricRunner extends RobolectricGradleTestRunner {
15 | public AppRobolectricRunner(Class> klass) throws InitializationError {
16 | super(klass);
17 | }
18 |
19 | protected AndroidManifest getAppManifest(Config config) {
20 | AndroidManifest appManifest = super.getAppManifest(config);
21 | FsFile androidManifestFile = appManifest.getAndroidManifestFile();
22 |
23 | if (androidManifestFile.exists()) {
24 | return appManifest;
25 | } else {
26 | String moduleRoot = getModuleRootPath(config);
27 | androidManifestFile = FileFsFile.from(moduleRoot, appManifest.getAndroidManifestFile().getPath().replace("bundles", "manifests/full"));
28 | FsFile resDirectory = FileFsFile.from(moduleRoot, appManifest.getResDirectory().getPath());
29 | FsFile assetsDirectory = FileFsFile.from(moduleRoot, appManifest.getAssetsDirectory().getPath());
30 | return new AndroidManifest(androidManifestFile, resDirectory, assetsDirectory);
31 | }
32 | }
33 |
34 | private String getModuleRootPath(Config config) {
35 | String moduleRoot = config.constants().getResource("").toString().replace("file:", "");
36 | return moduleRoot.substring(0, moduleRoot.indexOf("/build"));
37 | }
38 | }
--------------------------------------------------------------------------------
/commons/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | repositories{
4 | flatDir {
5 | dirs 'libs'
6 | }
7 | }
8 |
9 | android {
10 | compileSdkVersion rootProject.ext.compileSdkVersion
11 | buildToolsVersion rootProject.ext.buildToolsVersion
12 |
13 | defaultConfig {
14 | minSdkVersion rootProject.ext.minSdkVersion
15 | targetSdkVersion rootProject.ext.targetSdkVersion
16 | versionCode 1
17 | versionName "1.0"
18 | }
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 |
26 | packagingOptions {
27 | exclude 'META-INF/LICENSE'
28 | exclude 'META-INF/LICENSE.txt'
29 | exclude 'META-INF/NOTICE'
30 | exclude 'META-INF/NOTICE.txt'
31 | }
32 |
33 |
34 | compileOptions {
35 | sourceCompatibility JavaVersion.VERSION_1_6
36 | targetCompatibility JavaVersion.VERSION_1_6
37 | }
38 |
39 | }
40 |
41 | dependencies {
42 | compile fileTree(dir: 'libs', include: ['*.jar'])
43 | compile fileTree(dir: 'libs', include: ['*.aar'])
44 |
45 | compile "com.android.support:appcompat-v7:${rootProject.ext.appcompatVersion}"
46 |
47 | compile "com.marvinlabs:android-floatinglabel-widgets:${rootProject.ext.floatingWidgets}"
48 | compile "com.nineoldandroids:library:${rootProject.ext.nineOlds}"
49 | compile "org.apache.commons:commons-lang3:${rootProject.ext.commonsLang}"
50 | compile "commons-io:commons-io:${rootProject.ext.commonsIo}"
51 |
52 | compile "com.balysv:material-ripple:${rootProject.ext.materialRipple}"
53 | compile "com.joanzapata.pdfview:android-pdfview:${rootProject.ext.pdfView}"
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/list_item_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
17 |
18 |
22 |
23 |
28 |
29 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/util/CountUtil.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.util;
2 |
3 | import java.text.DecimalFormat;
4 |
5 | /**
6 | * Utility methods for formatting counts
7 | *
8 | * Common uses:
9 | * CountUtil.{@link #getFormattedCount getFormattedCount}(1200000); // returns "1.2m"
10 | */
11 |
12 | public class CountUtil {
13 |
14 | /**
15 | * @see #getFormattedCount(Long)
16 | */
17 | public static String getFormattedCount(int count) {
18 | return getFormattedCount(Long.valueOf(count));
19 | }
20 |
21 | /**
22 | * @see #getFormattedCount(Long)
23 | */
24 | public static String getFormattedCount(String count) {
25 | return getFormattedCount(Long.parseLong(count));
26 | }
27 |
28 | /**
29 | * Used to format a given number into a short representation.
30 | *
31 | * Examples:
32 | * Given 9100, will return "9.1k".
33 | * Given 8100000, will return "8.1m"
34 | * Given 10, will return 10"
35 | *
36 | * @param count Value to convert.
37 | * @return Formatted value (see examples)
38 | */
39 | public static String getFormattedCount(Long count) {
40 | final String unit;
41 | final Double dbl;
42 | final DecimalFormat format = new DecimalFormat("#.#");
43 | if (count < 1000) {
44 | return format.format(count);
45 | } else if (count < 1000000) {
46 | unit = "k";
47 | dbl = count / 1000.0;
48 | } else if (count < 1000000000) {
49 | unit = "m";
50 | dbl = count / 1000000.0;
51 | } else {
52 | unit = "b";
53 | dbl = count / 1000000000.0;
54 | }
55 | return format.format(dbl) + unit;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/app/src/main/java/com/richardradics/cleanaa/repository/api/model/openweatherwrapper/Weather.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.cleanaa.repository.api.model.openweatherwrapper;
2 |
3 |
4 | import com.google.gson.annotations.Expose;
5 |
6 |
7 | public class Weather {
8 |
9 | @Expose
10 | private Integer id;
11 | @Expose
12 | private String main;
13 | @Expose
14 | private String description;
15 | @Expose
16 | private String icon;
17 |
18 | /**
19 | *
20 | * @return
21 | * The id
22 | */
23 | public Integer getId() {
24 | return id;
25 | }
26 |
27 | /**
28 | *
29 | * @param id
30 | * The id
31 | */
32 | public void setId(Integer id) {
33 | this.id = id;
34 | }
35 |
36 | /**
37 | *
38 | * @return
39 | * The main
40 | */
41 | public String getMain() {
42 | return main;
43 | }
44 |
45 | /**
46 | *
47 | * @param main
48 | * The main
49 | */
50 | public void setMain(String main) {
51 | this.main = main;
52 | }
53 |
54 | /**
55 | *
56 | * @return
57 | * The description
58 | */
59 | public String getDescription() {
60 | return description;
61 | }
62 |
63 | /**
64 | *
65 | * @param description
66 | * The description
67 | */
68 | public void setDescription(String description) {
69 | this.description = description;
70 | }
71 |
72 | /**
73 | *
74 | * @return
75 | * The icon
76 | */
77 | public String getIcon() {
78 | return icon;
79 | }
80 |
81 | /**
82 | *
83 | * @param icon
84 | * The icon
85 | */
86 | public void setIcon(String icon) {
87 | this.icon = icon;
88 | }
89 |
90 | }
91 |
--------------------------------------------------------------------------------
/app/src/main/java/com/richardradics/cleanaa/domain/City.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.cleanaa.domain;
2 |
3 | /**
4 | * Created by radicsrichard on 15. 05. 14..
5 | */
6 | public class City {
7 |
8 | private Long id;
9 | private String name;
10 | private String country;
11 |
12 | public String getName() {
13 | return name;
14 | }
15 |
16 | public void setName(String name) {
17 | this.name = name;
18 | }
19 |
20 | public Long getId() {
21 | return id;
22 | }
23 |
24 | public void setId(Long id) {
25 | this.id = id;
26 | }
27 |
28 | public String getCountry() {
29 | return country;
30 | }
31 |
32 | public void setCountry(String country) {
33 | this.country = country;
34 | }
35 |
36 |
37 | @Override
38 | public boolean equals(Object o) {
39 | if (this == o) return true;
40 | if (o == null || getClass() != o.getClass()) return false;
41 |
42 | City city = (City) o;
43 |
44 | if (country != null ? !country.equals(city.country) : city.country != null) return false;
45 | if (id != null ? !id.equals(city.id) : city.id != null) return false;
46 | if (name != null ? !name.equals(city.name) : city.name != null) return false;
47 |
48 | return true;
49 | }
50 |
51 | @Override
52 | public int hashCode() {
53 | int result = id != null ? id.hashCode() : 0;
54 | result = 31 * result + (name != null ? name.hashCode() : 0);
55 | result = 31 * result + (country != null ? country.hashCode() : 0);
56 | return result;
57 | }
58 |
59 | @Override
60 | public String toString() {
61 | return "City{" +
62 | "id=" + id +
63 | ", name='" + name + '\'' +
64 | ", country='" + country + '\'' +
65 | '}';
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/helper/TelephonyHelper.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.helper;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.net.Uri;
6 | import android.telephony.TelephonyManager;
7 |
8 | /**
9 | * Created by Richard Radics on 2015.02.11..
10 | */
11 | public class TelephonyHelper {
12 |
13 | /**
14 | * Starts the dial activity with SIM enabled check.
15 | * @param context
16 | * @param phone
17 | */
18 | public static void startDialActivityWithSimCheck(Context context, String phone) {
19 | if (isTelephonyEnabled(context)) {
20 | Intent intent = new Intent(Intent.ACTION_DIAL);
21 | intent.setData(Uri.parse("tel:" + clearPhoneText(phone)));
22 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
23 | context.startActivity(intent);
24 | }
25 | }
26 |
27 |
28 | /**
29 | * Starts the dial activity.
30 | * @param context
31 | * @param phone
32 | */
33 | public static void startDialActivity(Context context, String phone) {
34 | Intent intent = new Intent(Intent.ACTION_DIAL);
35 | intent.setData(Uri.parse("tel:" + clearPhoneText(phone)));
36 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
37 | context.startActivity(intent);
38 | }
39 |
40 | /**
41 | * Checks the device has sim card.
42 | * @param context
43 | * @return
44 | */
45 | public static boolean isTelephonyEnabled(Context context) {
46 | TelephonyManager tm = (TelephonyManager) context.getSystemService(context.TELEPHONY_SERVICE);
47 | return tm != null && tm.getSimState() == TelephonyManager.SIM_STATE_READY;
48 | }
49 |
50 | public static String clearPhoneText(String phone){
51 | String s = phone.replace("/", "");
52 | String s2 = s.replace("-","");
53 | return s2;
54 | }
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/widget/kenburnsview/MathUtils.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.widget.kenburnsview;
2 |
3 | /**
4 | * Created by radicsrichard on 15. 04. 24..
5 | */
6 |
7 | import android.graphics.RectF;
8 |
9 | /**
10 | * Helper class to perform math computations.
11 | */
12 | public final class MathUtils {
13 |
14 | /**
15 | * Truncates a float number {@code f} to {@code decimalPlaces}.
16 | * @param f the number to be truncated.
17 | * @param decimalPlaces the amount of decimals that {@code f}
18 | * will be truncated to.
19 | * @return a truncated representation of {@code f}.
20 | */
21 | protected static float truncate(float f, int decimalPlaces) {
22 | float decimalShift = (float) Math.pow(10, decimalPlaces);
23 | return Math.round(f * decimalShift) / decimalShift;
24 | }
25 |
26 |
27 | /**
28 | * Checks whether two {@link RectF} have the same aspect ratio.
29 | * @param r1 the first rect.
30 | * @param r2 the second rect.
31 | * @return {@code true} if both rectangles have the same aspect ratio,
32 | * {@code false} otherwise.
33 | */
34 | protected static boolean haveSameAspectRatio(RectF r1, RectF r2) {
35 | // Reduces precision to avoid problems when comparing aspect ratios.
36 | float srcRectRatio = MathUtils.truncate(MathUtils.getRectRatio(r1), 2);
37 | float dstRectRatio = MathUtils.truncate(MathUtils.getRectRatio(r2), 2);
38 |
39 | // Compares aspect ratios that allows for a tolerance range of [0, 0.01]
40 | return (Math.abs(srcRectRatio-dstRectRatio) <= 0.01f);
41 | }
42 |
43 |
44 | /**
45 | * Computes the aspect ratio of a given rect.
46 | * @param rect the rect to have its aspect ratio computed.
47 | * @return the rect aspect ratio.
48 | */
49 | protected static float getRectRatio(RectF rect) {
50 | return rect.width() / rect.height();
51 | }
52 | }
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/util/NetworkUtil.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.util;
2 |
3 | import android.content.Context;
4 | import android.net.ConnectivityManager;
5 |
6 | /**
7 | * Created by Richard Radics on 2015.02.11..
8 | */
9 | public class NetworkUtil {
10 |
11 | /**
12 | * Checks the internet is active.
13 | * @param context
14 | * @return
15 | */
16 | public static boolean checkInternetIsActive(Context context) {
17 | ConnectivityManager connec = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
18 | android.net.NetworkInfo wifi = connec.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
19 | android.net.NetworkInfo mobile = connec.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
20 |
21 | if (wifi.isConnected() || mobile.isConnected()) {
22 | return true;
23 | }
24 |
25 | return false;
26 |
27 | }
28 |
29 | /**
30 | * Checks wifi is active.
31 | * @param context
32 | * @return
33 | */
34 | public static boolean checkWifiIsActive(Context context) {
35 | ConnectivityManager connec = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
36 | android.net.NetworkInfo wifi = connec.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
37 | if (wifi.isConnected()) {
38 | return true;
39 | }
40 | return false;
41 | }
42 |
43 | /**
44 | * Checks mobile network is active.
45 | * @param context
46 | * @return
47 | */
48 | public static boolean checkMobileIsActive(Context context) {
49 | ConnectivityManager connec = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
50 | android.net.NetworkInfo mobile = connec.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
51 | if (mobile.isConnected()) {
52 | return true;
53 | }
54 | return false;
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/core/src/main/java/com/richardradics/core/retrofit/BaseRetrofitClient.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.core.retrofit;
2 |
3 | import com.richardradics.core.error.NetworkErrorHandler;
4 | import com.richardradics.core.navigation.Navigator;
5 | import com.squareup.okhttp.OkHttpClient;
6 |
7 | import org.androidannotations.annotations.Bean;
8 | import org.androidannotations.annotations.EBean;
9 |
10 | import java.net.CookieHandler;
11 | import java.util.concurrent.TimeUnit;
12 |
13 | import retrofit.RestAdapter;
14 | import retrofit.client.OkClient;
15 |
16 | /**
17 | * Created by radicsrichard on 15. 04. 28..
18 | */
19 | @EBean
20 | public class BaseRetrofitClient {
21 |
22 | @Bean
23 | protected Navigator navigator;
24 |
25 |
26 | protected static OkHttpClient okHttpClient;
27 |
28 | @Bean
29 | protected BaseRetryHandler defaultRetryHandler;
30 |
31 | @Bean
32 | protected ConnectivityAwareUrlClient connectivityAwareUrlClient;
33 |
34 | @Bean
35 | protected NetworkErrorHandler networkErrorHandler;
36 |
37 | public T initRestAdapter(String ENDPOINT, Class restInterface, BaseRetryHandler baseRetryHandler) {
38 | okHttpClient = new OkHttpClient();
39 | okHttpClient.setCookieHandler(CookieHandler.getDefault());
40 | okHttpClient.setConnectTimeout(10, TimeUnit.MINUTES);
41 | connectivityAwareUrlClient.setWrappedClient(new OkClient(okHttpClient));
42 | connectivityAwareUrlClient.setRetryHandler(baseRetryHandler);
43 |
44 | RestAdapter restAdapter = new RestAdapter.Builder()
45 | .setEndpoint(ENDPOINT)
46 | .setClient(connectivityAwareUrlClient)
47 | // .setLogLevel(RestAdapter.LogLevel.FULL)
48 | .build();
49 | return restAdapter.create(restInterface);
50 | }
51 |
52 | public T initRestAdapter(String ENDPOINT, Class restInterface) {
53 | return initRestAdapter(ENDPOINT, restInterface, defaultRetryHandler);
54 | }
55 |
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/widget/ExpandableHeightGridView.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.widget;
2 |
3 | import android.content.Context;
4 | import android.util.AttributeSet;
5 | import android.view.MotionEvent;
6 | import android.view.ViewGroup;
7 | import android.widget.GridView;
8 |
9 | /**
10 | * Created by Richard Radics on 2014.12.11..
11 | */
12 | public class ExpandableHeightGridView extends GridView
13 | {
14 |
15 | boolean expanded = false;
16 |
17 | public ExpandableHeightGridView(Context context)
18 | {
19 | super(context);
20 | }
21 |
22 | public ExpandableHeightGridView(Context context, AttributeSet attrs)
23 | {
24 | super(context, attrs);
25 | }
26 |
27 | public ExpandableHeightGridView(Context context, AttributeSet attrs,
28 | int defStyle)
29 | {
30 | super(context, attrs, defStyle);
31 | }
32 |
33 | public boolean isExpanded()
34 | {
35 | return expanded;
36 | }
37 |
38 | @Override
39 | public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
40 | {
41 | /* // HACK! TAKE THAT ANDROID!
42 | if (isExpanded())
43 | {
44 |
45 | // Calculate entire height by providing a very large height hint.
46 | // View.MEASURED_SIZE_MASK represents the largest height possible.
47 | int expandSpec = MeasureSpec.makeMeasureSpec(MEASURED_SIZE_MASK,
48 | MeasureSpec.AT_MOST);
49 | super.onMeasure(widthMeasureSpec, expandSpec);
50 |
51 | ViewGroup.LayoutParams params = getLayoutParams();
52 | params.height = getMeasuredHeight();
53 | }
54 | else
55 | {
56 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
57 | }*/
58 | super.onMeasure(widthMeasureSpec, heightMeasureSpec);
59 | }
60 |
61 | public void setExpanded(boolean expanded)
62 | {
63 | this.expanded = expanded;
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/app/src/main/java/com/richardradics/cleanaa/repository/api/model/openweatherwrapper/OpenWeatherWrapper.java:
--------------------------------------------------------------------------------
1 |
2 | package com.richardradics.cleanaa.repository.api.model.openweatherwrapper;
3 |
4 | import com.google.gson.annotations.Expose;
5 | import com.google.gson.annotations.SerializedName;
6 |
7 | import java.util.ArrayList;
8 |
9 |
10 | public class OpenWeatherWrapper {
11 |
12 | @Expose
13 | private String message;
14 | @Expose
15 | private String cod;
16 | @Expose
17 | private Integer count;
18 | @Expose
19 | @SerializedName("list")
20 | private java.util.List list = new ArrayList();
21 |
22 | /**
23 | *
24 | * @return
25 | * The message
26 | */
27 | public String getMessage() {
28 | return message;
29 | }
30 |
31 | /**
32 | *
33 | * @param message
34 | * The message
35 | */
36 | public void setMessage(String message) {
37 | this.message = message;
38 | }
39 |
40 | /**
41 | *
42 | * @return
43 | * The cod
44 | */
45 | public String getCod() {
46 | return cod;
47 | }
48 |
49 | /**
50 | *
51 | * @param cod
52 | * The cod
53 | */
54 | public void setCod(String cod) {
55 | this.cod = cod;
56 | }
57 |
58 | /**
59 | *
60 | * @return
61 | * The count
62 | */
63 | public Integer getCount() {
64 | return count;
65 | }
66 |
67 | /**
68 | *
69 | * @param count
70 | * The count
71 | */
72 | public void setCount(Integer count) {
73 | this.count = count;
74 | }
75 |
76 | /**
77 | *
78 | * @return
79 | * The list
80 | */
81 | public java.util.List getList() {
82 | return list;
83 | }
84 |
85 | /**
86 | *
87 | * @param list
88 | * The list
89 | */
90 | public void setList(java.util.List list) {
91 | this.list = list;
92 | }
93 |
94 | }
95 |
--------------------------------------------------------------------------------
/core/build.workaround-missing-resource.gradle:
--------------------------------------------------------------------------------
1 | // Workaround for missing test resources when run unit tests within android studio.
2 | // This copy the test resources next to the test classes for each variant.
3 | // Tracked at https://github.com/nenick/AndroidStudioAndRobolectric/issues/7
4 | // Original solution comes from https://code.google.com/p/android/issues/detail?id=136013#c10
5 |
6 | gradle.projectsEvaluated {
7 | // Base path which is recognized by android studio.
8 | def testClassesPath = "${buildDir}/intermediates/classes/test/"
9 | // Copy must be done for each variant.
10 | def variants = android.libraryVariants.collect()
11 |
12 | variants.each { variant ->
13 | def variationName = variant.name.capitalize()
14 |
15 | // Get the flavor and also merge flavor groups.
16 | def productFlavorNames = variant.productFlavors.collect { it.name.capitalize() }
17 | if (productFlavorNames.isEmpty()) {
18 | productFlavorNames = [""]
19 | }
20 | productFlavorNames = productFlavorNames.join('')
21 |
22 | // Base path addition for this specific variant.
23 | def variationPath = variant.buildType.name;
24 | if (productFlavorNames != null && !productFlavorNames.isEmpty()) {
25 | variationPath = uncapitalize(productFlavorNames) + "/${variationPath}"
26 | }
27 |
28 | // Specific copy task for each variant
29 | def copyTestResourcesTask = project.tasks.create("copyTest${variationName}Resources", Copy)
30 | copyTestResourcesTask.from("${projectDir}/src/test/resources")
31 | copyTestResourcesTask.into("${testClassesPath}/${variationPath}")
32 | copyTestResourcesTask.execute()
33 | }
34 | }
35 |
36 | def uncapitalize(String str) {
37 | int strLen;
38 | if (str == null || (strLen = str.length()) == 0) {
39 | return str;
40 | }
41 | return new StringBuffer(strLen)
42 | .append(Character.toLowerCase(str.charAt(0)))
43 | .append(str.substring(1))
44 | .toString();
45 | }
--------------------------------------------------------------------------------
/app/build.workaround-missing-resource.gradle:
--------------------------------------------------------------------------------
1 | // Workaround for missing test resources when run unit tests within android studio.
2 | // This copy the test resources next to the test classes for each variant.
3 | // Tracked at https://github.com/nenick/AndroidStudioAndRobolectric/issues/7
4 | // Original solution comes from https://code.google.com/p/android/issues/detail?id=136013#c10
5 |
6 | gradle.projectsEvaluated {
7 | // Base path which is recognized by android studio.
8 | def testClassesPath = "${buildDir}/intermediates/classes/test/"
9 | // Copy must be done for each variant.
10 | def variants = android.applicationVariants.collect()
11 |
12 | variants.each { variant ->
13 | def variationName = variant.name.capitalize()
14 |
15 | // Get the flavor and also merge flavor groups.
16 | def productFlavorNames = variant.productFlavors.collect { it.name.capitalize() }
17 | if (productFlavorNames.isEmpty()) {
18 | productFlavorNames = [""]
19 | }
20 | productFlavorNames = productFlavorNames.join('')
21 |
22 | // Base path addition for this specific variant.
23 | def variationPath = variant.buildType.name;
24 | if (productFlavorNames != null && !productFlavorNames.isEmpty()) {
25 | variationPath = uncapitalize(productFlavorNames) + "/${variationPath}"
26 | }
27 |
28 | // Specific copy task for each variant
29 | def copyTestResourcesTask = project.tasks.create("copyTest${variationName}Resources", Copy)
30 | copyTestResourcesTask.from("${projectDir}/src/test/resources")
31 | copyTestResourcesTask.into("${testClassesPath}/${variationPath}")
32 | copyTestResourcesTask.execute()
33 | }
34 | }
35 |
36 | def uncapitalize(String str) {
37 | int strLen;
38 | if (str == null || (strLen = str.length()) == 0) {
39 | return str;
40 | }
41 | return new StringBuffer(strLen)
42 | .append(Character.toLowerCase(str.charAt(0)))
43 | .append(str.substring(1))
44 | .toString();
45 | }
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/ui/ActivityAnimator.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.ui;
2 |
3 | import android.app.Activity;
4 |
5 | import com.richardradics.commons.R;
6 |
7 | /**
8 | * Created by Richard Radics on 2015.02.09..
9 | */
10 | public class ActivityAnimator {
11 |
12 | public static void flipHorizontalAnimation(Activity a)
13 | {
14 | a.overridePendingTransition(R.anim.flip_horizontal_in, R.anim.flip_horizontal_out);
15 | }
16 |
17 | public static void flipVerticalAnimation(Activity a)
18 | {
19 | a.overridePendingTransition(R.anim.flip_vertical_in, R.anim.flip_vertical_out);
20 | }
21 |
22 | public static void fadeAnimation(Activity a)
23 | {
24 | a.overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
25 | }
26 |
27 | public static void disappearTopLeftAnimation(Activity a)
28 | {
29 | a.overridePendingTransition(R.anim.disappear_top_left_in, R.anim.disappear_top_left_out);
30 | }
31 |
32 | public static void appearTopLeftAnimation(Activity a)
33 | {
34 | a.overridePendingTransition(R.anim.appear_top_left_in, R.anim.appear_top_left_out);
35 | }
36 |
37 | public static void disappearBottomRightAnimation(Activity a)
38 | {
39 | a.overridePendingTransition(R.anim.disappear_bottom_right_in, R.anim.disappear_bottom_right_out);
40 | }
41 |
42 | public static void appearBottomRightAnimation(Activity a)
43 | {
44 | a.overridePendingTransition(R.anim.appear_bottom_right_in, R.anim.appear_bottom_right_out);
45 | }
46 |
47 | public static void unzoomAnimation(Activity a)
48 | {
49 | a.overridePendingTransition(R.anim.unzoom_in, R.anim.unzoom_out);
50 | }
51 |
52 | public static void PullRightPushLeft(Activity a)
53 | {
54 | a.overridePendingTransition(R.anim.pull_in_right, R.anim.push_out_left);
55 | }
56 | public static void PullLeftPushRight(Activity a)
57 | {
58 | a.overridePendingTransition(R.anim.pull_in_left, R.anim.push_out_right);
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/widget/echeckbox/EnhancedCheckbox.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.widget.echeckbox;
2 |
3 | import android.content.Context;
4 | import android.os.Build;
5 | import android.util.AttributeSet;
6 | import android.widget.CheckBox;
7 | import android.widget.CompoundButton;
8 |
9 | import com.richardradics.commons.util.ViewUtils;
10 |
11 | /**
12 | * An enhanced {@code CheckBox} that differentiates between user clicks and
13 | * programmatic clicks. In particular, the {@code OnCheckedChangeListener} is
14 | * not triggered when the state of the checkbox is changed
15 | * programmatically.
16 | *
17 | */
18 | public class EnhancedCheckbox extends CheckBox implements ProgrammaticallyCheckable{
19 | private CompoundButton.OnCheckedChangeListener mListener = null;
20 | public EnhancedCheckbox(Context context) {
21 | super(context);
22 | }
23 |
24 | public EnhancedCheckbox(Context context, AttributeSet attrs, int defStyle) {
25 | super(context, attrs, defStyle);
26 | }
27 |
28 | public EnhancedCheckbox(Context context, AttributeSet attrs) {
29 | super(context, attrs);
30 | }
31 |
32 | @Override
33 | public void setOnCheckedChangeListener(
34 | CompoundButton.OnCheckedChangeListener listener) {
35 | if (this.mListener == null) {this.mListener = listener;}
36 | super.setOnCheckedChangeListener(listener);
37 | }
38 | /**
39 | * Set the checked state of the checkbox programmatically. This is to differentiate it from a user click
40 | * @param checked Whether to check the checkbox
41 | */
42 | @Override
43 | public void setCheckedProgrammatically(boolean checked) {
44 | super.setOnCheckedChangeListener(null);
45 | super.setChecked(checked);
46 | super.setOnCheckedChangeListener(mListener);
47 | }
48 |
49 | @Override
50 | public int getCompoundPaddingLeft() {
51 | return ViewUtils.convertToPix(this.getResources().getDisplayMetrics().density, 20);
52 | }
53 |
54 |
55 | }
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/util/TextUtil.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.util;
2 |
3 | import android.content.Context;
4 | import android.util.DisplayMetrics;
5 | import android.util.TypedValue;
6 |
7 | /**
8 | * Created by Richard Radics on 2014.12.08..
9 | */
10 | public class TextUtil {
11 |
12 | private final static String EMPTY_STRING = "";
13 | private final static String THREE_DOTS = "…";
14 |
15 | public static String getLineSepartor() {
16 | return System.getProperty("line.separator");
17 | }
18 |
19 | public static String getDoubleLineSeparator() {
20 | StringBuilder sb = new StringBuilder();
21 | sb.append(getLineSepartor());
22 | sb.append(getLineSepartor());
23 | return sb.toString();
24 | }
25 |
26 | public static float getScaleIndependentSize(Context context, int fontSize) {
27 | DisplayMetrics metrics = context.getResources().getDisplayMetrics();
28 | float val = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, fontSize, metrics);
29 | return val;
30 | }
31 |
32 | /**
33 | * Truncates the string provided if its length is more than the value provided, and replaces
34 | * the extra text by "…" ensuring that the resulting length of the string will be
35 | * as maximum as the param maximumLengthAllowed
36 | *
37 | * @param maximumLengthAllowed The maximum allowed length for the provided string
38 | * @param string The string that will be truncated if necessary
39 | * @return The original string if its length is less than maximumLengthAllowed,
40 | * or the string cropped and … appended at the end if it's length is more than maximumLengthAllowed
41 | */
42 | public static String truncateIfLengthMoreThan(final int maximumLengthAllowed, String string) {
43 | if (string.length() > maximumLengthAllowed) {
44 | return string.substring(0, maximumLengthAllowed - THREE_DOTS.length()).concat(THREE_DOTS);
45 | } else {
46 | return string;
47 | }
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/util/DensityUtil.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.util;
2 |
3 | import android.content.Context;
4 | import android.content.res.Resources;
5 | import android.util.DisplayMetrics;
6 |
7 | /**
8 | * Created by mark on 2015. 03. 20..
9 | */
10 | public class DensityUtil {
11 | /**
12 | * This method converts dp unit to equivalent pixels, depending on device density.
13 | *
14 | * @param dp A value in dp (density independent pixels) unit. Which we need to convert into pixels
15 | * @param context Context to get resources and device specific display metrics
16 | * @return A float value to represent px equivalent to dp depending on device density
17 | */
18 | public static float convertDpToPixel(float dp, Context context){
19 | Resources resources = context.getResources();
20 | DisplayMetrics metrics = resources.getDisplayMetrics();
21 | float px = dp * (metrics.densityDpi / 160f);
22 | return px;
23 | }
24 |
25 | /**
26 | * This method converts device specific pixels to density independent pixels.
27 | *
28 | * @param px A value in px (pixels) unit. Which we need to convert into db
29 | * @param context Context to get resources and device specific display metrics
30 | * @return A float value to represent dp equivalent to px value
31 | */
32 | public static float convertPixelsToDp(float px, Context context){
33 | Resources resources = context.getResources();
34 | DisplayMetrics metrics = resources.getDisplayMetrics();
35 | float dp = px / (metrics.densityDpi / 160f);
36 | return dp;
37 | }
38 |
39 |
40 | public static int getDeviceWidthInPixes(Context context){
41 | DisplayMetrics metrics = context.getResources().getDisplayMetrics();
42 | return metrics.widthPixels;
43 |
44 | }
45 |
46 | public static int getDeviceHeightInPixes(Context context){
47 | DisplayMetrics metrics = context.getResources().getDisplayMetrics();
48 | return metrics.heightPixels;
49 |
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/widget/NonSwipeableViewPager.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.widget;
2 |
3 | import android.content.Context;
4 | import android.support.v4.view.ViewPager;
5 | import android.util.AttributeSet;
6 | import android.view.MotionEvent;
7 | import android.view.animation.DecelerateInterpolator;
8 | import android.widget.Scroller;
9 |
10 | import java.lang.reflect.Field;
11 |
12 | /**
13 | * Created by Richard Radics on 2015.02.11..
14 | */
15 | public class NonSwipeableViewPager extends ViewPager{
16 |
17 |
18 | private boolean enabled;
19 |
20 | public NonSwipeableViewPager(Context context, AttributeSet attrs) {
21 | super(context, attrs);
22 | this.enabled = true;
23 | setMyScroller();
24 | }
25 |
26 | @Override
27 | public boolean onTouchEvent(MotionEvent event) {
28 | if (this.enabled) {
29 | return super.onTouchEvent(event);
30 | }
31 |
32 | return false;
33 | }
34 |
35 | private void setMyScroller() {
36 | try {
37 | Class> viewpager = ViewPager.class;
38 | Field scroller = viewpager.getDeclaredField("mScroller");
39 | scroller.setAccessible(true);
40 | scroller.set(this, new SmoothScroller(getContext()));
41 | } catch (Exception e) {
42 | e.printStackTrace();
43 | }
44 | }
45 |
46 | public class SmoothScroller extends Scroller {
47 | public SmoothScroller(Context context) {
48 | super(context, new DecelerateInterpolator());
49 | }
50 |
51 | @Override
52 | public void startScroll(int startX, int startY, int dx, int dy, int duration) {
53 | super.startScroll(startX, startY, dx, dy, 300 /* 05 secs */);
54 | }
55 | }
56 |
57 | @Override
58 | public boolean onInterceptTouchEvent(MotionEvent event) {
59 | if (this.enabled) {
60 | return super.onInterceptTouchEvent(event);
61 | }
62 |
63 | return false;
64 | }
65 |
66 | public void setPagingEnabled(boolean enabled) {
67 | this.enabled = enabled;
68 | }
69 |
70 |
71 | }
72 |
--------------------------------------------------------------------------------
/core/src/main/java/com/richardradics/core/error/ErrorHandler.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.core.error;
2 |
3 | import android.content.Context;
4 | import android.util.Log;
5 |
6 | import com.nispok.snackbar.Snackbar;
7 | import com.nispok.snackbar.SnackbarManager;
8 | import com.richardradics.commons.util.ErrorUtil;
9 | import com.richardradics.core.navigation.Navigator;
10 |
11 | import org.androidannotations.annotations.Bean;
12 | import org.androidannotations.annotations.EBean;
13 | import org.androidannotations.annotations.RootContext;
14 | import org.androidannotations.annotations.UiThread;
15 |
16 | /**
17 | * Created by radicsrichard on 15. 04. 28..
18 | */
19 | @EBean
20 | public class ErrorHandler {
21 |
22 | @RootContext
23 | protected Context context;
24 |
25 | @Bean
26 | protected Navigator navigator;
27 |
28 | protected Integer snackBarBackgroundColor;
29 |
30 | public Integer getSnackBarBackgroundColor() {
31 | return snackBarBackgroundColor;
32 | }
33 |
34 | public void setSnackBarBackgroundColor(Integer snackBarBackgroundColor) {
35 | this.snackBarBackgroundColor = snackBarBackgroundColor;
36 | }
37 |
38 | public void handlerError(Exception e) {
39 | logError(e);
40 | }
41 |
42 | @UiThread
43 | protected void showError(String s) {
44 | if (navigator.isInForeground()) {
45 | Snackbar errorSnack;
46 | if (snackBarBackgroundColor != null) {
47 | errorSnack = Snackbar.with(context)
48 | .text(s)
49 | .duration(Snackbar.SnackbarDuration.LENGTH_SHORT)
50 | .color(snackBarBackgroundColor);
51 | } else {
52 | errorSnack = Snackbar.with(context)
53 | .text(s)
54 | .duration(Snackbar.SnackbarDuration.LENGTH_SHORT);
55 | }
56 |
57 | SnackbarManager.show(errorSnack, navigator.getCurrentActivityOnScreen());
58 | }
59 | }
60 |
61 | protected void logError(Throwable e) {
62 | String report = ErrorUtil.getErrorReport(e);
63 | Log.e("ErrorHandler Report:", report);
64 | }
65 |
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/util/DialogUtils.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.util;
2 |
3 | import android.app.Activity;
4 | import android.app.AlertDialog;
5 | import android.app.AlertDialog.Builder;
6 | import android.content.DialogInterface;
7 | import android.content.DialogInterface.OnClickListener;
8 | import android.text.SpannableString;
9 | import android.text.method.LinkMovementMethod;
10 | import android.text.util.Linkify;
11 | import android.widget.TextView;
12 |
13 | /**
14 | * Created by Richard Radics on 2015.02.12..
15 | */
16 | public class DialogUtils {
17 |
18 | /**
19 | * Show a model dialog box. The android.app.AlertDialog object is returned so that
20 | * you can specify an OnDismissListener (or other listeners) if required.
21 | * Note: show() is already called on the AlertDialog being returned.
22 | *
23 | * @param context The current Context or Activity that this method is called from.
24 | * @param message Message to display in the dialog.
25 | * @return AlertDialog that is being displayed.
26 | */
27 | public static AlertDialog quickDialog(final Activity context, final String message) {
28 | final SpannableString s = new SpannableString(message); //Make links clickable
29 | Linkify.addLinks(s, Linkify.ALL);
30 |
31 | Builder builder = new AlertDialog.Builder(context);
32 | builder.setMessage(s);
33 | builder.setPositiveButton(android.R.string.ok, closeDialogListener());
34 | AlertDialog dialog = builder.create();
35 | dialog.show();
36 |
37 | ((TextView) dialog.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance()); //Make links clickable
38 |
39 | return dialog;
40 | }
41 |
42 | /**
43 | * Simple listener event that closes the current dialog event when fired.
44 | *
45 | * @return DialogInterface.OnClickListener that can be attached to a button
46 | */
47 | public static OnClickListener closeDialogListener() {
48 | return new OnClickListener() {
49 | public void onClick(DialogInterface dialog, int id) {
50 | dialog.dismiss();
51 | }
52 | };
53 | }
54 |
55 |
56 | }
57 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/widget/HackyViewPager.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.widget;
2 |
3 |
4 | import android.content.Context;
5 | import android.support.v4.view.ViewPager;
6 | import android.util.AttributeSet;
7 | import android.view.MotionEvent;
8 |
9 | /**
10 | * Found at http://stackoverflow.com/questions/7814017/is-it-possible-to-disable-scrolling-on-a-viewpager.
11 | * Convenient way to temporarily disable ViewPager navigation while interacting with ImageView.
12 | *
13 | * Julia Zudikova
14 | */
15 |
16 | /**
17 | * Hacky fix for Issue #4 and
18 | * http://code.google.com/p/android/issues/detail?id=18990
19 | *
20 | * ScaleGestureDetector seems to mess up the touch events, which means that
21 | * ViewGroups which make use of onInterceptTouchEvent throw a lot of
22 | * IllegalArgumentException: pointerIndex out of range.
23 | *
24 | * There's not much I can do in my code for now, but we can mask the result by
25 | * just catching the problem and ignoring it.
26 | *
27 | * @author Chris Banes
28 | */
29 | public class HackyViewPager extends ViewPager {
30 |
31 | private boolean isLocked;
32 |
33 | public HackyViewPager(Context context) {
34 | super(context);
35 | isLocked = false;
36 | }
37 |
38 | public HackyViewPager(Context context, AttributeSet attrs) {
39 | super(context, attrs);
40 | isLocked = false;
41 | }
42 |
43 | @Override
44 | public boolean onInterceptTouchEvent(MotionEvent ev) {
45 | if (!isLocked) {
46 | try {
47 | return super.onInterceptTouchEvent(ev);
48 | } catch (IllegalArgumentException e) {
49 | e.printStackTrace();
50 | return false;
51 | }
52 | }
53 | return false;
54 | }
55 |
56 | @Override
57 | public boolean onTouchEvent(MotionEvent event) {
58 | if (!isLocked) {
59 | return super.onTouchEvent(event);
60 | }
61 | return false;
62 | }
63 |
64 | public void toggleLock() {
65 | isLocked = !isLocked;
66 | }
67 |
68 | public void setLocked(boolean isLocked) {
69 | this.isLocked = isLocked;
70 | }
71 |
72 | public boolean isLocked() {
73 | return isLocked;
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/core/src/test/java/com/richardradics/core/util/CoreRobolectricRunner.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.core.util;
2 |
3 |
4 | import org.junit.runners.model.InitializationError;
5 | import org.robolectric.RobolectricGradleTestRunner;
6 | import org.robolectric.annotation.Config;
7 | import org.robolectric.manifest.AndroidManifest;
8 | import org.robolectric.res.FileFsFile;
9 | import org.robolectric.res.FsFile;
10 |
11 | /**
12 | * Created by radicsrichard on 15. 05. 15..
13 | */
14 | public class CoreRobolectricRunner extends RobolectricGradleTestRunner {
15 |
16 | public CoreRobolectricRunner(Class> testClass) throws InitializationError {
17 | super(testClass);
18 |
19 | }
20 | protected AndroidManifest getAppManifest(Config config) {
21 | AndroidManifest appManifest = super.getAppManifest(config);
22 | FsFile androidManifestFile = appManifest.getAndroidManifestFile();
23 |
24 | // Workaround also wrong paths for res and assets.
25 | // This will be fixed with next robolectric release https://github.com/robolectric/robolectric/issues/1709
26 | if (androidManifestFile.exists()) {
27 | FsFile resDirectory = FileFsFile.from(appManifest.getAndroidManifestFile().getPath().replace("AndroidManifest.xml", "res"));
28 | FsFile assetsDirectory = FileFsFile.from(appManifest.getAndroidManifestFile().getPath().replace("AndroidManifest.xml", "assets"));
29 | return new AndroidManifest(androidManifestFile, resDirectory, assetsDirectory);
30 | } else {
31 | String moduleRoot = getModuleRootPath(config);
32 | androidManifestFile = FileFsFile.from(moduleRoot, appManifest.getAndroidManifestFile().getPath());
33 | FsFile resDirectory = FileFsFile.from(moduleRoot, appManifest.getAndroidManifestFile().getPath().replace("AndroidManifest.xml", "res"));
34 | FsFile assetsDirectory = FileFsFile.from(moduleRoot, appManifest.getAndroidManifestFile().getPath().replace("AndroidManifest.xml", "assets"));
35 | return new AndroidManifest(androidManifestFile, resDirectory, assetsDirectory);
36 | }
37 | }
38 |
39 | private String getModuleRootPath(Config config) {
40 | String moduleRoot = config.constants().getResource("").toString().replace("file:", "").replace("jar:", "");
41 | return moduleRoot.substring(0, moduleRoot.indexOf("/build"));
42 | }
43 | }
44 |
45 |
46 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/util/io/FileUtils.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.util.io;
2 |
3 |
4 | import java.io.File;
5 | import java.io.FileInputStream;
6 | import java.io.FileNotFoundException;
7 | import java.io.FileOutputStream;
8 | import java.io.IOException;
9 | import java.nio.channels.FileChannel;
10 |
11 |
12 | /**
13 | * Utility for the {@link java.io.File}.
14 | */
15 | @SuppressWarnings("unused") // public APIs
16 | public final class FileUtils {
17 | private FileUtils() {}
18 |
19 | /**
20 | * Create a new directory if not exists.
21 | * @param dir to create.
22 | * @return true if already exists, or newly created.
23 | */
24 | public static boolean makeDirsIfNeeded(File dir) {
25 | return dir.exists() || dir.mkdirs();
26 | }
27 |
28 | /**
29 | * Copy the file from the source to the destination.
30 | * @param source the source file to be copied.
31 | * @param destination the destination file to copy.
32 | * @see java.nio.channels.FileChannel#transferTo(long, long, java.nio.channels.WritableByteChannel).
33 | * @return the transferred byte count.
34 | * @throws FileNotFoundException
35 | * @throws IOException
36 | */
37 | public static long copy(File source, File destination) throws FileNotFoundException, IOException {
38 | FileInputStream in = null;
39 | FileOutputStream out = null;
40 | try {
41 | in = new FileInputStream(source);
42 | out = new FileOutputStream(destination);
43 | return copy(in, out);
44 | } finally {
45 | CloseableUtils.close(in);
46 | CloseableUtils.close(out);
47 | }
48 | }
49 |
50 | /**
51 | * Copy the file using streams.
52 | * @param in source.
53 | * @param out destination.
54 | * @see java.nio.channels.FileChannel#transferTo(long, long, java.nio.channels.WritableByteChannel)
55 | * @return the transferred byte count.
56 | * @throws IOException
57 | */
58 | public static long copy(FileInputStream in, FileOutputStream out) throws IOException {
59 | FileChannel source = null;
60 | FileChannel destination = null;
61 | try {
62 | source = in.getChannel();
63 | destination = out.getChannel();
64 | return source.transferTo(0, source.size(), destination);
65 | } finally {
66 | CloseableUtils.close(source);
67 | CloseableUtils.close(destination);
68 | }
69 | }
70 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/richardradics/cleanaa/mvp/view/model/MainModelAdapter.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.cleanaa.mvp.view.model;
2 |
3 | import android.support.v7.widget.RecyclerView;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 | import android.widget.ImageView;
8 | import android.widget.TextView;
9 |
10 | import com.richardradics.cleanaa.R;
11 | import com.squareup.picasso.Picasso;
12 |
13 | import java.util.ArrayList;
14 | import java.util.List;
15 |
16 | /**
17 | * Created by radicsrichard on 15. 05. 13..
18 | */
19 | public class MainModelAdapter extends RecyclerView.Adapter {
20 |
21 | private List models;
22 |
23 | public MainModelAdapter() {
24 | models = new ArrayList<>();
25 | }
26 |
27 | public MainModelAdapter(List models) {
28 | this.models = models;
29 | }
30 |
31 | @Override
32 | public MainModelAdapter.MainModelViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
33 | View modelView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_main, parent, false);
34 | return new MainModelViewHolder(modelView);
35 | }
36 |
37 | @Override
38 | public void onBindViewHolder(MainModelViewHolder holder, int position) {
39 | MainListViewModel model = models.get(position);
40 |
41 | holder.titleTextView.setText(model.getTitle());
42 | Picasso.with(holder.view.getContext()).load(model.getImageUrl()).into(holder.imageView);
43 |
44 | }
45 |
46 |
47 | @Override
48 | public int getItemCount() {
49 | return models.size();
50 | }
51 |
52 | public void clear() {
53 | models.clear();
54 | }
55 |
56 | public void addAll(List modelList) {
57 | for (MainListViewModel m : modelList) {
58 | if (!models.contains(m)) {
59 | models.add(m);
60 | }
61 | }
62 | }
63 |
64 | public MainListViewModel getItemByPosition(int position) {
65 | return models.get(position);
66 | }
67 |
68 | public class MainModelViewHolder extends RecyclerView.ViewHolder {
69 | View view;
70 |
71 | ImageView imageView;
72 | TextView titleTextView;
73 |
74 | public MainModelViewHolder(View itemView) {
75 | super(itemView);
76 | this.view = itemView;
77 | imageView = (ImageView) itemView.findViewById(R.id.image);
78 | titleTextView = (TextView) itemView.findViewById(R.id.text);
79 | }
80 | }
81 |
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/core/src/main/java/com/richardradics/core/util/LoadAndToast.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.core.util;
2 |
3 | import android.app.Activity;
4 | import android.app.Application;
5 | import android.content.Context;
6 |
7 | import com.nispok.snackbar.Snackbar;
8 | import com.nispok.snackbar.SnackbarManager;
9 | import com.richardradics.commons.util.DensityUtil;
10 | import com.richardradics.commons.widget.loadtoast.LoadToast;
11 | import com.richardradics.core.navigation.Navigator;
12 |
13 |
14 | import org.androidannotations.annotations.AfterInject;
15 | import org.androidannotations.annotations.Bean;
16 | import org.androidannotations.annotations.EBean;
17 | import org.androidannotations.annotations.RootContext;
18 |
19 | /**
20 | * Created by mark on 2015. 04. 29..
21 | */
22 | @EBean(scope = EBean.Scope.Singleton)
23 | public class LoadAndToast {
24 | @RootContext
25 | Context context;
26 |
27 | @Bean
28 | CommonUseCases commonUseCases;
29 |
30 | LoadToast loadToast;
31 | Snackbar loadingSnackBar;
32 |
33 |
34 | protected void init(Context context) {
35 | if (context != null) {
36 | loadToast = new LoadToast(context);
37 | setupLoadToast();
38 | loadingSnackBar = Snackbar.with(context);
39 | setupSnackBar();
40 | }
41 | }
42 |
43 | protected void setupLoadToast() {
44 | if (loadToast != null) {
45 | loadToast.setTranslationY((commonUseCases.getScreenSize().y-commonUseCases.getNavigationBarHeight() - commonUseCases.getScreenSize().y / 5)-5);
46 | // loadToast.setTranslationY(Float.floatToIntBits(DensityUtil.convertPixelsToDp(commonUseCases.getScreenSize().y,context) - DensityUtil.convertPixelsToDp(commonUseCases.getScreenSize().y/7,context)));
47 | }
48 | }
49 |
50 | protected void setupSnackBar() {
51 | if (loadingSnackBar != null) {
52 | loadingSnackBar.duration(Snackbar.SnackbarDuration.LENGTH_SHORT);
53 | }
54 | }
55 |
56 | public void showLoading(Context context, String message) {
57 | if (loadingSnackBar == null)
58 | init(context);
59 | loadToast.setText(message);
60 | loadToast.show();
61 | }
62 |
63 | public void endLoading(boolean success) {
64 | if (loadToast != null)
65 | if (success)
66 | loadToast.success();
67 | else
68 | loadToast.error();
69 | }
70 |
71 |
72 | public void showMessage(Context context, String message) {
73 | if (loadToast == null)
74 | init(context);
75 |
76 | loadingSnackBar.text(message);
77 | SnackbarManager.show(loadingSnackBar);
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/domain/MethodChainer.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.domain;
2 |
3 | import com.richardradics.commons.helper.DataHelper;
4 |
5 | import java.util.HashMap;
6 | import java.util.Map;
7 |
8 | /**
9 | * Created by radicsrichard on 15. 04. 20..
10 | */
11 | public class MethodChainer {
12 |
13 | public interface ProgressListener{
14 | void onMethodProgressStart();
15 | void onMethodProgressChanged(int percent, int tasksRemaining, int tasksDone);
16 | void onMethodProgressFinish();
17 | }
18 |
19 | private int tempTaskCount = 0;
20 | private int taskCount = 0;
21 | private ProgressListener mListener;
22 |
23 |
24 | public ProgressListener getProgressListener() {
25 | return mListener;
26 | }
27 |
28 | public void setProgressListener(ProgressListener mListener) {
29 | this.mListener = mListener;
30 | }
31 |
32 | Map methodCalledMap;
33 |
34 | public MethodChainer(){
35 | this.methodCalledMap = new HashMap();
36 | }
37 |
38 | public void addMethod(String methodName){
39 | taskCount++;
40 | methodCalledMap.put(methodName,Boolean.FALSE);
41 | }
42 |
43 | public void start(){
44 |
45 | if(mListener != null){
46 | mListener.onMethodProgressStart();
47 | }
48 |
49 | for(Map.Entry b : methodCalledMap.entrySet()){
50 | b.setValue(Boolean.FALSE);
51 | }
52 |
53 | }
54 |
55 | public synchronized void setCalled(String method){
56 | methodCalledMap.put(method, Boolean.TRUE);
57 |
58 | if(mListener != null) {
59 | if (isAllCalled()) {
60 | mListener.onMethodProgressFinish();
61 | }else{
62 | notifyProgressChange();
63 | }
64 | }
65 | }
66 |
67 | private void notifyProgressChange(){
68 | if(mListener != null){
69 | int taskready = taskCount-tempTaskCount;
70 | mListener.onMethodProgressChanged(DataHelper.getPercent(taskready, taskCount),tempTaskCount, taskready);
71 | }
72 | }
73 |
74 | public Boolean isCalled(String method){
75 | return methodCalledMap.get(method);
76 | }
77 |
78 | public synchronized Boolean isAllCalled(){
79 | Boolean result = Boolean.TRUE;
80 | tempTaskCount = 0;
81 | for(Map.Entry b : methodCalledMap.entrySet()){
82 | if(!b.getValue()){
83 | tempTaskCount++;
84 | result = Boolean.FALSE;
85 | }
86 | }
87 |
88 |
89 |
90 | return result;
91 | }
92 |
93 |
94 | }
95 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/helper/MakeUp.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.helper;
2 |
3 | /**
4 | * Created by radicsrichard on 15. 03. 17..
5 | */
6 | import android.graphics.Typeface;
7 | import android.text.Spannable;
8 | import android.text.SpannableString;
9 | import android.text.style.BackgroundColorSpan;
10 | import android.text.style.ForegroundColorSpan;
11 | import android.text.style.RelativeSizeSpan;
12 | import android.text.style.StrikethroughSpan;
13 | import android.text.style.StyleSpan;
14 | import android.text.style.UnderlineSpan;
15 |
16 | public class MakeUp
17 | {
18 | private final Spannable sb;
19 |
20 | public MakeUp( String input )
21 | {
22 | sb = new SpannableString( input );
23 | }
24 |
25 | public MakeUp strikethrough( int start, int length )
26 | {
27 | final StrikethroughSpan span = new StrikethroughSpan();
28 | sb.setSpan( span, start, start + length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE );
29 | return this;
30 | }
31 |
32 | public MakeUp underline( int start, int length )
33 | {
34 | final UnderlineSpan span = new UnderlineSpan();
35 | sb.setSpan( span, start, start + length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE );
36 | return this;
37 | }
38 |
39 | public MakeUp boldify( int start, int length )
40 | {
41 | final StyleSpan span = new StyleSpan( android.graphics.Typeface.BOLD );
42 | sb.setSpan( span, start, start + length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE );
43 | return this;
44 | }
45 |
46 | public MakeUp italize( int start, int length )
47 | {
48 | final StyleSpan span = new StyleSpan( Typeface.ITALIC );
49 | sb.setSpan( span, start, start + length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE );
50 | return this;
51 | }
52 |
53 | public MakeUp colorize( int start, int length, int color )
54 | {
55 | final ForegroundColorSpan span = new ForegroundColorSpan( color );
56 | sb.setSpan( span, start, start + length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE );
57 | return this;
58 | }
59 |
60 | public MakeUp mark( int start, int length, int color )
61 | {
62 | final BackgroundColorSpan span = new BackgroundColorSpan( color );
63 | sb.setSpan( span, start, start + length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE );
64 | return this;
65 | }
66 |
67 | public MakeUp proportionate( int start, int length, float proportion )
68 | {
69 | final RelativeSizeSpan span = new RelativeSizeSpan( proportion );
70 | sb.setSpan( span, start, start + length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE );
71 | return this;
72 | }
73 |
74 | public Spannable apply()
75 | {
76 | return sb;
77 | }
78 | }
--------------------------------------------------------------------------------
/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 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
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 Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/app/src/main/java/com/richardradics/cleanaa/app/CleanActivity.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.cleanaa.app;
2 |
3 | import android.content.res.TypedArray;
4 | import android.support.v7.widget.Toolbar;
5 | import android.util.TypedValue;
6 | import android.view.View;
7 | import android.widget.TextView;
8 |
9 | import com.richardradics.cleanaa.R;
10 | import com.richardradics.core.app.BaseActivity;
11 | import com.richardradics.core.navigation.Navigator;
12 |
13 | import org.androidannotations.annotations.AfterViews;
14 | import org.androidannotations.annotations.Bean;
15 | import org.androidannotations.annotations.EActivity;
16 | import org.androidannotations.annotations.OptionsItem;
17 | import org.androidannotations.annotations.ViewById;
18 |
19 | /**
20 | * Created by radicsrichard on 15. 05. 13..
21 | */
22 | @EActivity
23 | public class CleanActivity extends BaseActivity {
24 |
25 | @ViewById(R.id.toolbar)
26 | protected Toolbar toolbar;
27 |
28 |
29 | @ViewById(R.id.toolbar_title)
30 | protected TextView titleTextView;
31 |
32 | @Bean
33 | protected CleanErrorHandler cleanErrorHandler;
34 |
35 | public TextView getTitleTextView() {
36 | return titleTextView;
37 | }
38 |
39 | public void setTitleTextView(TextView titleTextView) {
40 | this.titleTextView = titleTextView;
41 | }
42 |
43 | public Toolbar getToolbar() {
44 | return toolbar;
45 | }
46 |
47 | public void setToolbar(Toolbar toolbar) {
48 | this.toolbar = toolbar;
49 | }
50 |
51 | @AfterViews
52 | protected void onBaseViewFinish() {
53 | initToolBar();
54 | }
55 |
56 |
57 | protected void initToolBar() {
58 | if (toolbar != null) {
59 | toolbar.setTitleTextColor(getResources().getColor(android.R.color.white));
60 | titleTextView = (TextView) findViewById(R.id.toolbar_title);
61 | setSupportActionBar(toolbar);
62 | titleTextView.setText(getTitle());
63 | toolbar.setNavigationIcon(R.drawable.ic_backarrow);
64 | }
65 | }
66 |
67 | @OptionsItem(android.R.id.home)
68 | protected void homeSelected() {
69 | Navigator.navigateUp(this);
70 | }
71 |
72 | protected int getActionBarSize() {
73 | TypedValue typedValue = new TypedValue();
74 | int[] textSizeAttr = new int[]{R.attr.actionBarSize};
75 | int indexOfAttrTextSize = 0;
76 | TypedArray a = obtainStyledAttributes(typedValue.data, textSizeAttr);
77 | int actionBarSize = a.getDimensionPixelSize(indexOfAttrTextSize, -1);
78 | a.recycle();
79 | return actionBarSize;
80 | }
81 |
82 |
83 | protected int getScreenHeight() {
84 | return findViewById(android.R.id.content).getHeight();
85 | }
86 |
87 | }
88 |
--------------------------------------------------------------------------------
/app/src/main/java/com/richardradics/cleanaa/repository/api/OpenWeatherClient.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.cleanaa.repository.api;
2 |
3 | import android.util.Log;
4 |
5 | import com.richardradics.cleanaa.domain.City;
6 | import com.richardradics.cleanaa.exception.GetCitiesException;
7 | import com.richardradics.cleanaa.repository.CleanRepository;
8 | import com.richardradics.cleanaa.repository.api.model.openweatherwrapper.OpenWeatherWrapper;
9 | import com.richardradics.cleanaa.app.CleanDatabase;
10 | import com.richardradics.core.retrofit.BaseRetrofitClient;
11 |
12 | import org.androidannotations.annotations.AfterInject;
13 | import org.androidannotations.annotations.Bean;
14 | import org.androidannotations.annotations.EBean;
15 |
16 | import java.util.List;
17 |
18 | import retrofit.Callback;
19 | import retrofit.RetrofitError;
20 | import retrofit.client.Response;
21 |
22 | /**
23 | * Created by radicsrichard on 15. 05. 13..
24 | */
25 | @EBean(scope = EBean.Scope.Singleton)
26 | public class OpenWeatherClient extends BaseRetrofitClient implements CleanRepository {
27 |
28 | private static final String TAG = "WeatherClient";
29 | public static String ENDPOINT = "http://api.openweathermap.org";
30 |
31 | @Bean
32 | OpenWeatherResponseMapper openWeatherResponseMapper;
33 |
34 | private static OpenWeatherAPI openWeatherAPI;
35 |
36 | @AfterInject
37 | void onAfterInjectFinished() {
38 | openWeatherAPI = initRestAdapter(ENDPOINT, OpenWeatherAPI.class);
39 | }
40 |
41 |
42 | public void getCitiesAsync(final Double latitude, final Double longitude, final Integer count) {
43 | openWeatherAPI.getWeatherItems(latitude, longitude, count, new Callback() {
44 | @Override
45 | public void success(OpenWeatherWrapper openWeatherWrapper, Response response) {
46 |
47 | }
48 |
49 | @Override
50 | public void failure(RetrofitError error) {
51 | networkErrorHandler.handlerError(error);
52 | }
53 | });
54 | }
55 |
56 | public List getCities(Double latitude, Double longitude, Integer count) {
57 | try {
58 | OpenWeatherWrapper openWeatherWrapper = openWeatherAPI.getWeatherItems(latitude, longitude, count);
59 | return openWeatherResponseMapper.mapResponse(openWeatherWrapper);
60 | } catch (Exception exception) {
61 | return throwGetCitiesException(exception);
62 | }
63 | }
64 |
65 | private List throwGetCitiesException(Exception retrofitError) {
66 | Log.e(TAG, "Error during fetching cities");
67 | GetCitiesException getCitiesException = new GetCitiesException();
68 | getCitiesException.setStackTrace(retrofitError.getStackTrace());
69 | throw getCitiesException;
70 | }
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/galgo/GalgoService.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.galgo;
2 |
3 | /**
4 | * Created by PontApps on 2015.03.11..
5 | */
6 |
7 | import android.app.Service;
8 | import android.content.Intent;
9 | import android.graphics.PixelFormat;
10 | import android.os.Binder;
11 | import android.os.IBinder;
12 | import android.text.Spannable;
13 | import android.text.SpannableString;
14 | import android.text.TextUtils;
15 | import android.text.style.BackgroundColorSpan;
16 | import android.view.WindowManager;
17 | import android.widget.TextView;
18 |
19 | import java.util.ArrayDeque;
20 | import java.util.Collection;
21 | import java.util.Queue;
22 |
23 | public class GalgoService extends Service {
24 |
25 | private final IBinder mBinder = new LocalBinder();
26 | private TextView mTextView;
27 | private GalgoOptions mOptions;
28 | private final Queue mLines = new ArrayDeque();
29 |
30 | public class LocalBinder extends Binder {
31 | public GalgoService getService() {
32 | return GalgoService.this;
33 | }
34 | }
35 |
36 | @Override
37 | public IBinder onBind(Intent intent) {
38 | this.mOptions = intent.getExtras().getParcelable(Galgo.ARG_OPTIONS);
39 | return mBinder;
40 | }
41 |
42 | @Override
43 | public void onCreate() {
44 | super.onCreate();
45 |
46 | mTextView = new TextView(this);
47 |
48 | WindowManager.LayoutParams params = new WindowManager.LayoutParams(
49 | WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT,
50 | WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,
51 | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT);
52 | WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
53 | wm.addView(mTextView, params);
54 | }
55 |
56 | public void displayText(String text) {
57 | mLines.add(text);
58 | if (mLines.size() > mOptions.numberOfLines) {
59 | mLines.poll();
60 | }
61 |
62 | redraw(mLines);
63 | }
64 |
65 | private void redraw(Collection texts) {
66 | mTextView.setTextSize(mOptions.textSize);
67 | mTextView.setTextColor(mOptions.textColor);
68 |
69 | Spannable spannable = new SpannableString(TextUtils.join("\n", texts));
70 | spannable.setSpan(new BackgroundColorSpan(mOptions.backgroundColor), 0, spannable.length(),
71 | Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
72 |
73 | mTextView.setText(spannable);
74 | }
75 |
76 | @Override
77 | public void onDestroy() {
78 | super.onDestroy();
79 | if (mTextView != null) {
80 | WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
81 | wm.removeView(mTextView);
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/core/src/main/java/com/richardradics/core/app/ErrorActivity.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.core.app;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.support.v7.app.ActionBarActivity;
6 | import android.view.View;
7 | import android.widget.Button;
8 | import android.widget.TextView;
9 |
10 | import com.richardradics.core.R;
11 |
12 | /**
13 | * Created by radicsrichard on 15. 04. 28..
14 | */
15 | public class ErrorActivity extends ActionBarActivity {
16 |
17 | public final static String STACKTRACE_ARG = "strack-arg";
18 | public final static String EXCEPTION_TYPE_ARG = "extype-arg";
19 | public final static String CAUSE_ARG = "cause-arg";
20 | public final static String DEVICE_INFO_ARG = "devinf-arg";
21 |
22 | TextView errorStactTraceTextView;
23 | Button errorConfirmButton;
24 | TextView errorDeviceInfoTextView;
25 | TextView errorCauseTextView;
26 | TextView errorExceptionTypeTextView;
27 |
28 |
29 | @Override
30 | public void onCreate(Bundle savedInstanceState) {
31 | super.onCreate(savedInstanceState);
32 |
33 |
34 | setContentView(R.layout.activity_error);
35 |
36 | errorStactTraceTextView = (TextView) findViewById(R.id.errorStactTraceTextView);
37 | errorConfirmButton = (Button) findViewById(R.id.errorConfirmButton);
38 | errorDeviceInfoTextView = (TextView) findViewById(R.id.errorDeviceInfoTextView);
39 | errorCauseTextView = (TextView) findViewById(R.id.errorCauseTextView);
40 | errorExceptionTypeTextView = (TextView) findViewById(R.id.errorExceptionTypeTextView);
41 |
42 | onAfterViewFInish();
43 | }
44 |
45 |
46 | private void onAfterViewFInish() {
47 | if (getIntent().hasExtra(CAUSE_ARG)) {
48 | errorCauseTextView.setText(getIntent().getStringExtra(CAUSE_ARG));
49 | }
50 |
51 | if (getIntent().hasExtra(DEVICE_INFO_ARG)) {
52 | errorDeviceInfoTextView.setText(getIntent().getStringExtra(DEVICE_INFO_ARG));
53 | }
54 |
55 | if (getIntent().hasExtra(EXCEPTION_TYPE_ARG)) {
56 | errorExceptionTypeTextView.setText(getIntent().getStringExtra(EXCEPTION_TYPE_ARG));
57 | }
58 |
59 | if (getIntent().hasExtra(STACKTRACE_ARG)) {
60 | errorStactTraceTextView.setText(getIntent().getStringExtra(STACKTRACE_ARG));
61 | }
62 |
63 | errorConfirmButton.setOnClickListener(new View.OnClickListener() {
64 | @Override
65 | public void onClick(View v) {
66 | Intent intent = new Intent(Intent.ACTION_MAIN);
67 | intent.addCategory(Intent.CATEGORY_HOME);
68 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
69 | startActivity(intent);
70 | }
71 | });
72 | }
73 |
74 | @Override
75 | public void setContentView(int layoutResID) {
76 | super.setContentView(R.layout.activity_error);
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/core/src/main/java/com/richardradics/core/app/BaseActivity.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.core.app;
2 |
3 | import android.content.Intent;
4 | import android.os.Bundle;
5 | import android.support.v7.app.ActionBarActivity;
6 | import android.util.Log;
7 |
8 | import com.richardradics.commons.util.ErrorUtil;
9 | import com.richardradics.core.error.NetworkErrorHandler;
10 | import com.richardradics.core.navigation.Navigator;
11 | import com.richardradics.core.retrofit.NoConnectivityListener;
12 | import com.richardradics.core.util.CommonUseCases;
13 | import com.richardradics.core.util.LoadAndToast;
14 |
15 |
16 | import org.androidannotations.annotations.Bean;
17 | import org.androidannotations.annotations.EActivity;
18 |
19 | /**
20 | * Created by radicsrichard on 15. 04. 28..
21 | */
22 | @EActivity
23 | public abstract class BaseActivity extends ActionBarActivity implements NoConnectivityListener {
24 |
25 | @Bean
26 | protected Navigator navigator;
27 |
28 | @Bean
29 | protected CommonUseCases commonUseCases;
30 |
31 | @Bean
32 | protected NetworkErrorHandler networkErrorHandler;
33 |
34 | @Bean
35 | protected LoadAndToast progress;
36 |
37 | @Override
38 | protected void onCreate(Bundle savedInstanceState) {
39 | super.onCreate(savedInstanceState);
40 | Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
41 | @Override
42 | public void uncaughtException(Thread thread, Throwable e) {
43 | handleUncaughtException(thread, e);
44 | }
45 | });
46 | }
47 |
48 | protected void handleUncaughtException(Thread thread, Throwable e) {
49 | Log.d("Report :: ", ErrorUtil.getErrorReport(e));
50 |
51 | String cause = ErrorUtil.getCause(e);
52 | String errorType = ErrorUtil.getExceptionType(e);
53 | String stackTrace = ErrorUtil.getStrackTrace(e);
54 | String deviceInfo = ErrorUtil.getDeviceInfo();
55 |
56 | Intent i = new Intent(getApplicationContext(), ErrorActivity.class);
57 | i.putExtra(ErrorActivity.EXCEPTION_TYPE_ARG, errorType);
58 | i.putExtra(ErrorActivity.STACKTRACE_ARG, stackTrace);
59 | i.putExtra(ErrorActivity.DEVICE_INFO_ARG, deviceInfo);
60 | i.putExtra(ErrorActivity.CAUSE_ARG, cause);
61 |
62 | i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
63 | i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
64 | startActivity(i);
65 |
66 |
67 | System.exit(0);
68 | }
69 |
70 |
71 | @Override
72 | protected void onResume() {
73 | super.onResume();
74 | navigator.setCurrentActivityOnScreen(this);
75 | }
76 |
77 | @Override
78 | protected void onPause() {
79 | super.onPause();
80 | navigator.setCurrentActivityOnScreen(null);
81 | }
82 |
83 | @Override
84 | public void onNoConnectivityError(){
85 | progress.endLoading(false);
86 | }
87 |
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/commons/src/main/res/drawable/btn_check.xml:
--------------------------------------------------------------------------------
1 |
2 |
16 |
17 |
18 |
19 |
20 |
21 |
24 |
27 |
28 |
31 |
34 |
35 |
38 |
41 |
42 |
45 |
48 |
49 |
50 |
51 |
52 |
54 |
56 |
57 |
59 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/widget/ObservableScrollView.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.widget;
2 |
3 | /**
4 | * Created by radicsrichard on 15. 03. 17..
5 | */
6 |
7 | import android.content.Context;
8 | import android.util.AttributeSet;
9 | import android.view.View;
10 | import android.widget.ScrollView;
11 |
12 | public class ObservableScrollView extends ScrollView {
13 |
14 | private ScrollViewListener scrollViewListener = null;
15 |
16 | public ObservableScrollView(Context context) {
17 | super(context);
18 | }
19 |
20 | public ObservableScrollView(Context context, AttributeSet attrs, int defStyle) {
21 | super(context, attrs, defStyle);
22 | }
23 |
24 | public ObservableScrollView(Context context, AttributeSet attrs) {
25 | super(context, attrs);
26 | }
27 |
28 | public void setScrollViewListener(ScrollViewListener scrollViewListener) {
29 | this.scrollViewListener = scrollViewListener;
30 | }
31 |
32 |
33 | @Override
34 | public void fling(int velocityY) {
35 | super.fling(velocityY);
36 |
37 | }
38 |
39 | @Override
40 | protected void onScrollChanged(int x, int y, int oldx, int oldy) {
41 | super.onScrollChanged(x, y, oldx, oldy);
42 |
43 | if (y == 0) {
44 | if (scrollViewListener != null) {
45 | scrollViewListener.onScrollStartHitted();
46 | }
47 | }
48 |
49 | if (scrollViewListener != null) {
50 | scrollViewListener.onScrollChanged(this, x, y, oldx, oldy);
51 | }
52 |
53 |
54 | if (Math.abs(y - oldy) < 2 || y >= getMeasuredHeight() || y == 0) {
55 | if (scrollViewListener != null) {
56 | scrollViewListener.onScrollEnded();
57 | }
58 | }
59 |
60 |
61 | int dy = y - oldy;
62 | if (dy > 10) {
63 | if (scrollViewListener != null) {
64 | scrollViewListener.onScrollUp();
65 | }
66 | } else if (dy < -10) {
67 | if (scrollViewListener != null) {
68 | scrollViewListener.onScrollDown();
69 | }
70 | }
71 |
72 | View view = (View) this.getChildAt(this.getChildCount() - 1);
73 | int diff = (view.getBottom() - (this.getHeight() + this.getScrollY()));
74 |
75 | // if diff is zero, then the bottom has been reached
76 | if (diff == 0) {
77 | if (scrollViewListener != null) {
78 | scrollViewListener.onScrollBottomHitted();
79 | }
80 | }
81 |
82 | }
83 |
84 | public interface ScrollViewListener {
85 |
86 | void onScrollStartHitted();
87 |
88 | void onScrollChanged(ObservableScrollView scrollView, int x, int y, int oldx, int oldy);
89 |
90 | void onScrollBottomHitted();
91 |
92 | void onScrollUp();
93 |
94 | void onScrollDown();
95 |
96 | void onScrollEnded();
97 |
98 | }
99 |
100 | }
--------------------------------------------------------------------------------
/commons/src/main/java/com/richardradics/commons/widget/AutoBackgroundButton.java:
--------------------------------------------------------------------------------
1 | package com.richardradics.commons.widget;
2 |
3 |
4 | import android.content.Context;
5 | import android.graphics.Color;
6 | import android.graphics.ColorFilter;
7 | import android.graphics.LightingColorFilter;
8 | import android.graphics.drawable.Drawable;
9 | import android.graphics.drawable.LayerDrawable;
10 | import android.util.AttributeSet;
11 | import android.widget.Button;
12 |
13 | /**
14 | * Applies a pressed state color filter or disabled state alpha for the button's background
15 | * drawable.
16 | *
17 | * @author richardradics
18 | */
19 | public class AutoBackgroundButton extends Button {
20 |
21 | public AutoBackgroundButton(Context context) {
22 | super(context);
23 | }
24 |
25 | public AutoBackgroundButton(Context context, AttributeSet attrs) {
26 | super(context, attrs);
27 | }
28 |
29 | public AutoBackgroundButton(Context context, AttributeSet attrs, int defStyle) {
30 | super(context, attrs, defStyle);
31 | }
32 |
33 | @Override
34 | public void setBackgroundDrawable(Drawable d) {
35 | // Replace the original background drawable (e.g. image) with a LayerDrawable that
36 | // contains the original drawable.
37 | AutoBackgroundButtonBackgroundDrawable layer = new AutoBackgroundButtonBackgroundDrawable(d);
38 | super.setBackgroundDrawable(layer);
39 | }
40 |
41 | /**
42 | * The stateful LayerDrawable used by this button.
43 | */
44 | protected class AutoBackgroundButtonBackgroundDrawable extends LayerDrawable {
45 |
46 | // The color filter to apply when the button is pressed
47 | protected ColorFilter _pressedFilter = new LightingColorFilter(Color.LTGRAY, 1);
48 | // Alpha value when the button is disabled
49 | protected int _disabledAlpha = 100;
50 | // Alpha value when the button is enabled
51 | protected int _fullAlpha = 255;
52 |
53 | public AutoBackgroundButtonBackgroundDrawable(Drawable d) {
54 | super(new Drawable[] { d });
55 | }
56 |
57 | @Override
58 | protected boolean onStateChange(int[] states) {
59 | boolean enabled = false;
60 | boolean pressed = false;
61 |
62 | for (int state : states) {
63 | if (state == android.R.attr.state_enabled)
64 | enabled = true;
65 | else if (state == android.R.attr.state_pressed)
66 | pressed = true;
67 | }
68 |
69 | mutate();
70 | if (enabled && pressed) {
71 | setColorFilter(_pressedFilter);
72 | } else if (!enabled) {
73 | setColorFilter(null);
74 | setAlpha(_disabledAlpha);
75 | } else {
76 | setColorFilter(null);
77 | setAlpha(_fullAlpha);
78 | }
79 |
80 | invalidateSelf();
81 |
82 | return super.onStateChange(states);
83 | }
84 |
85 | @Override
86 | public boolean isStateful() {
87 | return true;
88 | }
89 | }
90 |
91 | }
92 |
--------------------------------------------------------------------------------