├── assets ├── images │ ├── social │ │ ├── twitter.png │ │ ├── facebook.png │ │ ├── linkedin.png │ │ ├── google_plus.png │ │ └── stackoverflow.png │ ├── general │ │ ├── avatar.jpeg │ │ └── readme-header.png │ ├── articles │ │ ├── pebble-icon.jpg │ │ ├── pebble-icon-2.jpg │ │ ├── pebble-icon-bike.jpg │ │ ├── pebble-introduction.png │ │ ├── pebble-little-helper.png │ │ ├── best-practice-application.png │ │ ├── http-volley-request-manager.png │ │ ├── best-practice-sharedprefarences.png │ │ └── http-volley-request-manager-lite.png │ └── gists │ │ ├── activity-toast.gif │ │ ├── view-animation-snake.gif │ │ ├── sample-activity-stack.png │ │ └── utilst-custom-toast-1.png └── css │ └── main.css ├── gists ├── model │ ├── localparser │ │ ├── parse │ │ │ ├── zip.parse.zip │ │ │ ├── XmlHandler.java │ │ │ ├── ParseMethod.java │ │ │ ├── JsonHandler.java │ │ │ ├── Utils.java │ │ │ ├── XmlParser.java │ │ │ └── JsonParser.java │ │ └── LocalParser.java │ ├── okhttp │ │ ├── okwrapper │ │ │ ├── zip.okwrapper.zip │ │ │ ├── XmlHandler.java │ │ │ ├── RequestCallback.java │ │ │ ├── JsonHandler.java │ │ │ ├── AbsCommand.java │ │ │ ├── StringConverter.java │ │ │ ├── JsonConverter.java │ │ │ ├── Tag.java │ │ │ ├── XmlConverter.java │ │ │ ├── ConvertMethod.java │ │ │ ├── RequestManager.java │ │ │ ├── ServerResponse.java │ │ │ └── AbsApi.java │ │ └── okwrapper.md │ ├── volley │ │ ├── authorization.md │ │ └── cache-image-loader.md │ └── async-data-loader.md ├── utils │ ├── security │ │ └── readme.md │ ├── string-comparator.md │ ├── resource-fetcher.md │ ├── random.md │ ├── dialog-helper.md │ ├── apk.md │ ├── keyboard.md │ ├── NetworkUtils.java │ ├── app-state-tracker.md │ ├── uri.md │ ├── log.md │ ├── PreferencesUtils.java │ ├── bitmap.java │ └── drawable.md ├── sample │ ├── close-stack-of-activities.md │ ├── boot-shutdown-receivers.md │ ├── battery-change-receiver.md │ ├── crop-photo.md │ └── activity-slide-animation.md ├── view │ ├── vertical-view-pager │ │ ├── VerticalDepthPageTransformer.java │ │ └── VerticalBaseTransformer.java │ ├── spinner-hint.md │ ├── map │ │ ├── TouchableSupportMapFragment.java │ │ └── TouchableFrameLayout.java │ ├── typeface-spannable.md │ ├── custom-actionbar-title.md │ ├── drawable │ │ ├── color-sates-list-drawable.md │ │ └── color-sate-list-drawable.md │ ├── activity-toast-factory.md │ ├── custom-toast.md │ ├── bullet-indicator.md │ ├── animation │ │ └── snake.md │ └── activity-toast.md ├── gradle │ ├── tips.md │ └── build-files.md ├── adapter │ ├── SimpleAdapter.java │ └── SimplePagerAdapter.java └── widget │ └── simple-implementation.md ├── README.md ├── articles ├── pebble │ └── Pebble. Little Helper.md └── android │ ├── http │ └── Volley Request Manager - Lite.md │ └── best practice │ ├── Best Practice. SharedPreferences.md │ └── Best Practice. Application.md └── index.html /assets/images/social/twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yakivmospan/android-snippets/HEAD/assets/images/social/twitter.png -------------------------------------------------------------------------------- /assets/images/general/avatar.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yakivmospan/android-snippets/HEAD/assets/images/general/avatar.jpeg -------------------------------------------------------------------------------- /assets/images/social/facebook.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yakivmospan/android-snippets/HEAD/assets/images/social/facebook.png -------------------------------------------------------------------------------- /assets/images/social/linkedin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yakivmospan/android-snippets/HEAD/assets/images/social/linkedin.png -------------------------------------------------------------------------------- /assets/images/social/google_plus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yakivmospan/android-snippets/HEAD/assets/images/social/google_plus.png -------------------------------------------------------------------------------- /assets/images/articles/pebble-icon.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yakivmospan/android-snippets/HEAD/assets/images/articles/pebble-icon.jpg -------------------------------------------------------------------------------- /assets/images/general/readme-header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yakivmospan/android-snippets/HEAD/assets/images/general/readme-header.png -------------------------------------------------------------------------------- /assets/images/gists/activity-toast.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yakivmospan/android-snippets/HEAD/assets/images/gists/activity-toast.gif -------------------------------------------------------------------------------- /assets/images/social/stackoverflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yakivmospan/android-snippets/HEAD/assets/images/social/stackoverflow.png -------------------------------------------------------------------------------- /assets/images/articles/pebble-icon-2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yakivmospan/android-snippets/HEAD/assets/images/articles/pebble-icon-2.jpg -------------------------------------------------------------------------------- /assets/images/articles/pebble-icon-bike.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yakivmospan/android-snippets/HEAD/assets/images/articles/pebble-icon-bike.jpg -------------------------------------------------------------------------------- /assets/images/gists/view-animation-snake.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yakivmospan/android-snippets/HEAD/assets/images/gists/view-animation-snake.gif -------------------------------------------------------------------------------- /gists/model/localparser/parse/zip.parse.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yakivmospan/android-snippets/HEAD/gists/model/localparser/parse/zip.parse.zip -------------------------------------------------------------------------------- /assets/images/articles/pebble-introduction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yakivmospan/android-snippets/HEAD/assets/images/articles/pebble-introduction.png -------------------------------------------------------------------------------- /assets/images/articles/pebble-little-helper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yakivmospan/android-snippets/HEAD/assets/images/articles/pebble-little-helper.png -------------------------------------------------------------------------------- /assets/images/gists/sample-activity-stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yakivmospan/android-snippets/HEAD/assets/images/gists/sample-activity-stack.png -------------------------------------------------------------------------------- /assets/images/gists/utilst-custom-toast-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yakivmospan/android-snippets/HEAD/assets/images/gists/utilst-custom-toast-1.png -------------------------------------------------------------------------------- /gists/model/okhttp/okwrapper/zip.okwrapper.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yakivmospan/android-snippets/HEAD/gists/model/okhttp/okwrapper/zip.okwrapper.zip -------------------------------------------------------------------------------- /assets/images/articles/best-practice-application.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yakivmospan/android-snippets/HEAD/assets/images/articles/best-practice-application.png -------------------------------------------------------------------------------- /assets/images/articles/http-volley-request-manager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yakivmospan/android-snippets/HEAD/assets/images/articles/http-volley-request-manager.png -------------------------------------------------------------------------------- /assets/images/articles/best-practice-sharedprefarences.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yakivmospan/android-snippets/HEAD/assets/images/articles/best-practice-sharedprefarences.png -------------------------------------------------------------------------------- /assets/images/articles/http-volley-request-manager-lite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yakivmospan/android-snippets/HEAD/assets/images/articles/http-volley-request-manager-lite.png -------------------------------------------------------------------------------- /gists/model/localparser/parse/XmlHandler.java: -------------------------------------------------------------------------------- 1 | import org.xml.sax.ContentHandler; 2 | 3 | public interface XmlHandler extends ContentHandler{ 4 | 5 | public ResultType getResult(); 6 | } 7 | -------------------------------------------------------------------------------- /gists/model/okhttp/okwrapper/XmlHandler.java: -------------------------------------------------------------------------------- 1 | import org.xml.sax.ContentHandler; 2 | 3 | public interface XmlHandler extends ContentHandler{ 4 | 5 | public ResultType getResult(); 6 | } 7 | -------------------------------------------------------------------------------- /gists/utils/security/readme.md: -------------------------------------------------------------------------------- 1 | One tool to manage key generation, key storing and encryption on different APIs of Android. 2 | 3 | Moved to seperate [repository](https://github.com/yakivmospan/scytale). 4 | -------------------------------------------------------------------------------- /gists/model/okhttp/okwrapper/RequestCallback.java: -------------------------------------------------------------------------------- 1 | import android.support.annotation.NonNull; 2 | 3 | /** 4 | * Created by Yakiv M. on 11.02.2015. 5 | */ 6 | public interface RequestCallback { 7 | 8 | public void onResponse(@NonNull ServerResponse response); 9 | } 10 | -------------------------------------------------------------------------------- /gists/model/localparser/parse/ParseMethod.java: -------------------------------------------------------------------------------- 1 | import android.support.annotation.NonNull; 2 | import android.support.annotation.Nullable; 3 | 4 | /** 5 | * Created by Yakiv M. on 10.02.2015. 6 | */ 7 | public interface ParseMethod { 8 | 9 | @Nullable 10 | public abstract R parse(@NonNull S source); 11 | } 12 | -------------------------------------------------------------------------------- /gists/sample/close-stack-of-activities.md: -------------------------------------------------------------------------------- 1 | ![Header](/assets/images/gists/sample-activity-stack.png) 2 | 3 | ```java 4 | public class ActivityC extends Activity{ 5 | ... 6 | 7 | public void startHomeActivity(){ 8 | Intent intent = new Intent(this, ActivityA.class); 9 | intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 10 | startActivity(intent); 11 | } 12 | } 13 | ``` 14 | -------------------------------------------------------------------------------- /gists/utils/string-comparator.md: -------------------------------------------------------------------------------- 1 | ```java 2 | import java.util.Comparator; 3 | 4 | public class StringComparator implements Comparator{ 5 | 6 | @Override 7 | public int compare(String lhs, String rhs) { 8 | if (lhs == null && rhs == null) { 9 | return 0; 10 | }else if (lhs == null) { 11 | return rhs.compareTo(lhs); 12 | } else { 13 | return lhs.compareTo(rhs); 14 | } 15 | } 16 | } 17 | ``` 18 | -------------------------------------------------------------------------------- /gists/model/localparser/parse/JsonHandler.java: -------------------------------------------------------------------------------- 1 | import org.json.JSONObject; 2 | 3 | public abstract class JsonHandler { 4 | public abstract void parse(String js); 5 | public abstract ResultType getResult(); 6 | 7 | public String optString(String theKey, JSONObject theJson) { 8 | return theJson.isNull(theKey) ? null : theJson.optString(theKey); 9 | } 10 | 11 | public String optString(String theKey, JSONObject theJson, String theDefaultValue) { 12 | return theJson.isNull(theKey) ? null : theJson.optString(theKey, theDefaultValue); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /gists/model/okhttp/okwrapper/JsonHandler.java: -------------------------------------------------------------------------------- 1 | import org.json.JSONObject; 2 | 3 | public abstract class JsonHandler { 4 | public abstract void parse(String js); 5 | public abstract ResultType getResult(); 6 | 7 | public String optString(String theKey, JSONObject theJson) { 8 | return theJson.isNull(theKey) ? null : theJson.optString(theKey); 9 | } 10 | 11 | public String optString(String theKey, JSONObject theJson, String theDefaultValue) { 12 | return theJson.isNull(theKey) ? null : theJson.optString(theKey, theDefaultValue); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /gists/model/okhttp/okwrapper/AbsCommand.java: -------------------------------------------------------------------------------- 1 | import com.squareup.okhttp.OkHttpClient; 2 | import com.squareup.okhttp.Request; 3 | 4 | import android.support.annotation.NonNull; 5 | 6 | /** 7 | * Created by Yakiv M. on 11.02.2015. 8 | */ 9 | public interface AbsCommand { 10 | public 11 | @NonNull 12 | OkHttpClient createClient(); 13 | 14 | public 15 | @NonNull 16 | Request createRequest(); 17 | 18 | public 19 | @NonNull 20 | ConvertMethod createConvertMethod(); 21 | 22 | public 23 | @NonNull 24 | void onResponse(ServerResponse response); 25 | } 26 | -------------------------------------------------------------------------------- /gists/model/localparser/LocalParser.java: -------------------------------------------------------------------------------- 1 | import android.content.Context; 2 | import android.support.annotation.NonNull; 3 | import android.support.annotation.Nullable; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | /** 9 | * Created by Yakiv M. on 10.02.2015. 10 | */ 11 | public class LocalParser { 12 | 13 | private Context mContext; 14 | 15 | public LocalParser(Context context) { 16 | mContext = context; 17 | } 18 | 19 | public 20 | @Nullable 21 | People parsePeople() { 22 | JsonParser parser = new JsonParser<>(new PeopleJHandler()); 23 | return parser.parse(Utils.openStream(mContext, "people")); 24 | } 25 | } -------------------------------------------------------------------------------- /gists/model/localparser/parse/Utils.java: -------------------------------------------------------------------------------- 1 | import android.content.Context; 2 | import android.content.res.AssetManager; 3 | import android.support.annotation.NonNull; 4 | import android.support.annotation.Nullable; 5 | 6 | import java.io.IOException; 7 | import java.io.InputStream; 8 | 9 | /** 10 | * Created by Yakiv M. on 10.02.2015. 11 | */ 12 | public class Utils { 13 | 14 | public static 15 | @Nullable 16 | InputStream openStream(@NonNull Context context, String path) { 17 | try { 18 | AssetManager assetManager = context.getAssets(); 19 | return assetManager.open(path); 20 | } catch (IOException e) { 21 | L.e(e.getMessage()); 22 | return null; 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /gists/model/okhttp/okwrapper/StringConverter.java: -------------------------------------------------------------------------------- 1 | import com.squareup.okhttp.ResponseBody; 2 | 3 | import android.support.annotation.NonNull; 4 | import android.support.annotation.Nullable; 5 | 6 | import java.io.BufferedReader; 7 | import java.io.IOException; 8 | import java.io.InputStream; 9 | import java.io.InputStreamReader; 10 | 11 | /** 12 | * Created by Yakiv M. on 09.02.2015. 13 | */ 14 | public class StringConverter extends ConvertMethod { 15 | @Override 16 | @Nullable 17 | protected String convertResult(@NonNull ResponseBody body) { 18 | try { 19 | return body.string(); 20 | } catch (IOException e) { 21 | L.e(e.getMessage()); 22 | } 23 | return null; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /gists/utils/resource-fetcher.md: -------------------------------------------------------------------------------- 1 | ### Utils: ResourceFetcher 2 | 3 | Some times we need find resource ID by it String name. This class will help to do this 4 | 5 | **Usage** 6 | 7 | ```java 8 | ResourceFetcher fetcher = new ResourceFetcher(context); 9 | 10 | ImageView view = ... 11 | view.setImageResource(fetcher.getDrawableId("name")); 12 | ``` 13 | 14 | **Sources** 15 | 16 | ```java 17 | public class ResourceFetcher { 18 | 19 | private Context mContext; 20 | 21 | public ResourceFetcher(Context context) { 22 | mContext = context.getApplicationContext(); 23 | } 24 | 25 | public int getDrawableId(String id) { 26 | return mContext.getResources().getIdentifier(id, "drawable", mContext.getPackageName()); 27 | } 28 | } 29 | ``` 30 | -------------------------------------------------------------------------------- /gists/utils/random.md: -------------------------------------------------------------------------------- 1 | ### Utils: Random 2 | 3 | Utils for generating random number from closed [min, max] range, while min <= max is true 4 | 5 | ```java 6 | import junit.framework.Assert; 7 | import java.util.Random; 8 | 9 | /** 10 | * Created by Yakiv M. on 28.11.2014. 11 | */ 12 | public class RandomUtils extends Random { 13 | 14 | /** 15 | * @param min generated value. Can't be > then max 16 | * @param max generated value 17 | * @return values in closed range [min, max]. 18 | */ 19 | public int nextInt(int min, int max) { 20 | Assert.assertFalse("min can't be > then max; values:[" + min + ", " + max + "]", min > max); 21 | if (min == max) { 22 | return max; 23 | } 24 | 25 | return nextInt(max - min + 1) + min; 26 | } 27 | } 28 | ``` 29 | -------------------------------------------------------------------------------- /gists/utils/dialog-helper.md: -------------------------------------------------------------------------------- 1 | ### Utils: DialogHelper 2 | 3 | Class that helps to **show/dismiss** `DialogFraments` allowing state loss 4 | 5 | ```java 6 | public class DialogHelper { 7 | 8 | public static void showAllowStateLoss(FragmentActivity activity, String tag, DialogFragment dialog) { 9 | if (activity != null && !activity.isFinishing()) { 10 | FragmentTransaction ft = activity.getSupportFragmentManager().beginTransaction(); 11 | ft.add(dialog,tag); 12 | ft.commitAllowingStateLoss(); 13 | } 14 | } 15 | 16 | 17 | public static void dismissAllowStateLoss(FragmentActivity activity, DialogFragment dialog) { 18 | if (activity != null && !activity.isFinishing()) { 19 | dialog.dismissAllowingStateLoss(); 20 | } 21 | } 22 | } 23 | ``` 24 | -------------------------------------------------------------------------------- /gists/model/okhttp/okwrapper/JsonConverter.java: -------------------------------------------------------------------------------- 1 | import com.squareup.okhttp.ResponseBody; 2 | 3 | import android.support.annotation.NonNull; 4 | import android.support.annotation.Nullable; 5 | 6 | import java.io.IOException; 7 | 8 | /** 9 | * Created by Yakiv M. on 09.02.2015. 10 | */ 11 | public class JsonConverter extends ConvertMethod { 12 | 13 | private final JsonHandler mHandler; 14 | 15 | public JsonConverter(@NonNull JsonHandler handler) { 16 | mHandler = handler; 17 | } 18 | 19 | @Override 20 | @Nullable 21 | protected S convertResult(@NonNull ResponseBody body) { 22 | try { 23 | String js = body.string(); 24 | if (js != null) { 25 | mHandler.parse(js); 26 | } 27 | } catch (IOException e) { 28 | L.e(e.getMessage()); 29 | } 30 | return mHandler.getResult(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /gists/model/okhttp/okwrapper/Tag.java: -------------------------------------------------------------------------------- 1 | import android.support.annotation.NonNull; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | /** 7 | * Created by Yakiv M. on 12.02.2015. 8 | */ 9 | public class Tag { 10 | 11 | private String[] mValues; 12 | 13 | public Tag(@NonNull String ...values) { 14 | mValues = values; 15 | } 16 | 17 | @Override 18 | public boolean equals(Object o) { 19 | if (this == o) { 20 | return true; 21 | } 22 | if (o == null || getClass() != o.getClass()) { 23 | return false; 24 | } 25 | 26 | Tag tag = (Tag) o; 27 | 28 | List values = Arrays.asList(mValues); 29 | for (int i = 0; i < tag.mValues.length; i++) { 30 | if( values.contains(tag.mValues[i])){ 31 | return true; 32 | } 33 | } 34 | return false; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Header](/assets/images/general/readme-header.png)](http://yakivmospan.github.io/android-codeview) 2 | == 3 | ### Gists 4 | 5 | - [Adapter](/gists/adapter) 6 | - [Gradle](/gists//gradle) 7 | - [Model](/gists/model) 8 | - [Sample](/gists/sample) 9 | - [Utils](/gists/utils) 10 | - [View](/gists/view) 11 | - [Spinner](/gists/spinner) 12 | - [Widget](/gists/widget) 13 | 14 | Please don't forget to star, fork and share this repo with you friends if you find it useful. 15 | [Visit my blog](http://yakivmospan.blogspot.com/) for more interesting stuff. Thanks! 16 | 17 | == 18 | 19 | [![Google Plus](/assets/images/social/google_plus.png)](https://plus.google.com/+YakivMospan) 20 | [![Twitter](/assets/images/social/twitter.png)](https://twitter.com/yakivmospan) 21 | [![Facebook](/assets/images/social/facebook.png)](https://www.facebook.com/yakiv.mospan) 22 | [![Linked In](/assets/images/social/linkedin.png)](https://www.linkedin.com/pub/yakiv-mospan/a8/a92/823) 23 | [![stackoverflow](/assets/images/social/stackoverflow.png)](http://stackoverflow.com/users/1805989/yakiv-mospan) 24 | -------------------------------------------------------------------------------- /gists/utils/apk.md: -------------------------------------------------------------------------------- 1 | ```java 2 | import android.content.Context; 3 | import android.content.pm.PackageInfo; 4 | import android.content.pm.PackageManager; 5 | import android.content.pm.Signature; 6 | import android.util.Base64; 7 | 8 | import java.security.MessageDigest; 9 | import java.security.NoSuchAlgorithmException; 10 | 11 | public class ApkUtils { 12 | 13 | public static void printKeyHash(Context context){ 14 | try { 15 | PackageInfo info = context.getPackageManager().getPackageInfo( 16 | "com.facebook.samples.hellofacebook", 17 | PackageManager.GET_SIGNATURES); 18 | for (Signature signature : info.signatures) { 19 | MessageDigest md = MessageDigest.getInstance("SHA"); 20 | md.update(signature.toByteArray()); 21 | L.d(Base64.encodeToString(md.digest(), Base64.DEFAULT)); 22 | } 23 | } catch (PackageManager.NameNotFoundException e) { 24 | 25 | } catch (NoSuchAlgorithmException e) { 26 | 27 | } 28 | } 29 | } 30 | ``` 31 | -------------------------------------------------------------------------------- /gists/utils/keyboard.md: -------------------------------------------------------------------------------- 1 | ### Utils: Keyboard 2 | 3 | Some times we need to hide/show keyboard after some actions. This class will help to do this : 4 | 5 | ```java 6 | public class KeyboardUtils { 7 | 8 | public static void showKeyboard(View theView) { 9 | Context context = theView.getContext(); 10 | Object service = context.getSystemService(Context.INPUT_METHOD_SERVICE); 11 | 12 | InputMethodManager imm = (InputMethodManager) service; 13 | if (imm != null) { 14 | imm.toggleSoftInput( 15 | InputMethodManager.SHOW_FORCED, 16 | InputMethodManager.HIDE_IMPLICIT_ONLY); 17 | } 18 | } 19 | 20 | public static void hideKeyboard(View theView) { 21 | Context context = theView.getContext(); 22 | Object service = context.getSystemService(Context.INPUT_METHOD_SERVICE); 23 | 24 | InputMethodManager imm = (InputMethodManager) service; 25 | if (imm != null) { 26 | imm.hideSoftInputFromWindow(theView.getWindowToken(), 0); 27 | } 28 | } 29 | } 30 | ``` 31 | -------------------------------------------------------------------------------- /gists/view/vertical-view-pager/VerticalDepthPageTransformer.java: -------------------------------------------------------------------------------- 1 | package com.stacy.planets.controller.view; 2 | 3 | import android.view.View; 4 | 5 | /** 6 | * Created by T530 on 18/09/2014. 7 | */ 8 | public class VerticalDepthPageTransformer extends VerticalBaseTransformer { 9 | private static final float MIN_SCALE = 0.75f; 10 | 11 | @Override 12 | protected void onTransform(View view, float position) { 13 | if (position <= 0f) { 14 | view.setTranslationY(0f); 15 | view.setScaleX(1f); 16 | view.setScaleY(1f); 17 | } else if (position <= 1f) { 18 | final float scaleFactor = MIN_SCALE + (1 - MIN_SCALE) * (1 - Math.abs(position)); 19 | view.setAlpha(1 - position); 20 | view.setPivotX(0.5f * view.getWidth()); 21 | view.setTranslationY(view.getHeight() * -position); 22 | view.setScaleX(scaleFactor); 23 | view.setScaleY(scaleFactor); 24 | } 25 | } 26 | 27 | @Override 28 | protected boolean isPagingEnabled() { 29 | return true; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /gists/model/volley/authorization.md: -------------------------------------------------------------------------------- 1 | ### Volley: Authorization 2 | 3 | Example of adding authorization header to Volley Requests: 4 | 5 | 6 | ```java 7 | public class AuthRequest extends JsonObjectRequest { 8 | 9 | public AuthRequest(int method, String url, JSONObject jsonRequest, 10 | Response.Listener listener, 11 | Response.ErrorListener errorListener) { 12 | super(method, url, jsonRequest, listener, errorListener); 13 | } 14 | 15 | public AuthRequest(String url, JSONObject jsonRequest, 16 | Response.Listener listener, 17 | Response.ErrorListener errorListener) { 18 | super(url, jsonRequest, listener, errorListener); 19 | } 20 | 21 | @Override 22 | public Map getHeaders() throws AuthFailureError { 23 | return createBasicAuthHeader("user", "password"); 24 | } 25 | 26 | Map createBasicAuthHeader(String username, String password) { 27 | Map headerMap = new HashMap(); 28 | 29 | String credentials = username + ":" + password; 30 | String encodedCredentials = Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP); 31 | headerMap.put("Authorization", "Basic " + encodedCredentials); 32 | 33 | return headerMap; 34 | } 35 | } 36 | ``` 37 | -------------------------------------------------------------------------------- /gists/view/spinner-hint.md: -------------------------------------------------------------------------------- 1 | ### Spinner: Hint 2 | 3 | There is no default API to set hint on Spinner. To add it we will need a small workaround. 4 | 5 | ```java 6 | List objects = new ArrayList(); 7 | objects.add(firstItem); 8 | objects.add(secondItem); 9 | // add hint as last item 10 | objects.add(hint); 11 | 12 | HintAdapter adapter = new HintAdapter(context, objects, android.R.layout.simple_spinner_item); 13 | adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 14 | 15 | Spinner spinnerFilmType = (Spinner) findViewById(R.id.spinner); 16 | spinner.setAdapter(adapter); 17 | 18 | // show hint 19 | spinner.setSelection(adapter.getCount()); 20 | ``` 21 | 22 | Adapter source: 23 | 24 | ```java 25 | public class HintAdapter 26 | extends ArrayAdapter { 27 | 28 | public HintAdapter(Context theContext, List objects) { 29 | super(theContext, R.id.text1, R.id.text1, objects); 30 | } 31 | 32 | public HintAdapter(Context theContext, List objects, int theLayoutResId) { 33 | super(theContext, theLayoutResId, R.id.text1, objects); 34 | } 35 | 36 | @Override 37 | public int getCount() { 38 | // don't display last item. It is used as hint. 39 | int count = super.getCount(); 40 | return count > 0 ? count - 1 : count; 41 | } 42 | } 43 | ``` 44 | -------------------------------------------------------------------------------- /gists/sample/boot-shutdown-receivers.md: -------------------------------------------------------------------------------- 1 | **AndroidManifest.xml** 2 | ```xml 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | ``` 19 | 20 | **BootReceiver.java** 21 | ```java 22 | public class BootReceiver extends BroadcastReceiver { 23 | @Override 24 | public void onReceive(Context context, Intent intent) { 25 | //do your staf here, start service for example 26 | Intent startServiceIntent = new Intent(context, ApplicationService.class); 27 | context.startService(startServiceIntent); 28 | } 29 | } 30 | ``` 31 | 32 | **ShutdownReceiver.java** 33 | ```java 34 | public class ShutdownReceiver extends BroadcastReceiver { 35 | @Override 36 | public void onReceive(Context context, Intent intent) { 37 | //do your staf here, stop location tracking for example 38 | } 39 | } 40 | ``` 41 | -------------------------------------------------------------------------------- /gists/gradle/tips.md: -------------------------------------------------------------------------------- 1 | ### Gradle: Tips 2 | 3 | #### Change some class only for one flavor 4 | The task is to add new `SplashActivity.class` for `flavor10` and left old one for the rest flavors. 5 | **Rule**. Main can't contain classes that are in flavors 6 | 7 | There are to options to achieve this. 8 | 9 | **First one :** 10 | - Remove old `SplashActivity.class` from `main` 11 | - Add copies of it to all `flavors` except `flavor10` 12 | - Then create new `SplashActivity.class` for `flavor10` 13 | - **Change all** old `SplashActivity.class` in flavors that use it when you need to update it 14 | 15 | **Second one :** 16 | - Create `common` flavor 17 | - Move old `SplashActivity.class` from `main` inside it 18 | - Change source sets for all `flavors` that should use it 19 | ```java 20 | apply plugin: 'android' 21 | android { 22 | ///... 23 | signingConfigs {///...} 24 | buildTypes {///...} 25 | productFlavors {///...} 26 | 27 | sourceSets { 28 | flavor1 { 29 | java { 30 | srcDir 'src/common/java' 31 | } 32 | } 33 | ///... 34 | flavor9 { 35 | java { 36 | srcDir 'src/common/java' 37 | } 38 | } 39 | } 40 | } 41 | ``` 42 | - Create new `SplashActivity.class` for `flavor10` 43 | - **Change only one** old `SplashActivity.class` in `common` flavor when you need to update it 44 | -------------------------------------------------------------------------------- /gists/model/okhttp/okwrapper/XmlConverter.java: -------------------------------------------------------------------------------- 1 | import com.squareup.okhttp.ResponseBody; 2 | 3 | import org.xml.sax.InputSource; 4 | import org.xml.sax.SAXException; 5 | import org.xml.sax.XMLReader; 6 | 7 | import android.support.annotation.NonNull; 8 | import android.support.annotation.Nullable; 9 | 10 | import java.io.IOException; 11 | 12 | import javax.xml.parsers.ParserConfigurationException; 13 | import javax.xml.parsers.SAXParser; 14 | import javax.xml.parsers.SAXParserFactory; 15 | 16 | /** 17 | * Created by Yakiv M. on 09.02.2015. 18 | */ 19 | public class XmlConverter extends ConvertMethod { 20 | 21 | private final XmlHandler mHandler; 22 | 23 | public XmlConverter(@NonNull XmlHandler handler) { 24 | mHandler = handler; 25 | } 26 | 27 | @Override 28 | @Nullable 29 | protected S convertResult(@NonNull ResponseBody body) { 30 | 31 | final SAXParserFactory spf = SAXParserFactory.newInstance(); 32 | final SAXParser saxParser; 33 | try { 34 | saxParser = spf.newSAXParser(); 35 | 36 | final XMLReader xmlReader = saxParser.getXMLReader(); 37 | xmlReader.setContentHandler(mHandler); 38 | 39 | xmlReader.parse(new InputSource(body.byteStream())); 40 | return mHandler.getResult(); 41 | } catch (ParserConfigurationException | IOException | SAXException e) { 42 | L.e(e.getMessage()); 43 | return null; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /gists/model/okhttp/okwrapper/ConvertMethod.java: -------------------------------------------------------------------------------- 1 | import com.squareup.okhttp.Request; 2 | import com.squareup.okhttp.Response; 3 | import com.squareup.okhttp.ResponseBody; 4 | 5 | import android.support.annotation.NonNull; 6 | import android.support.annotation.Nullable; 7 | 8 | import java.io.IOException; 9 | 10 | /** 11 | * Created by Yakiv M. on 09.02.2015. 12 | */ 13 | 14 | public abstract class ConvertMethod { 15 | 16 | @Nullable 17 | protected abstract S convertResult(@NonNull ResponseBody body); 18 | 19 | protected final ServerResponse convert(@Nullable Response response) { 20 | ServerResponse result = new ServerResponse<>(); 21 | if (response != null) { 22 | result.setCode(response.code()); 23 | result.setSuccessufl(response.isSuccessful()); 24 | result.setHeaders(response.headers()); 25 | result.setSuccessResult(convertResult(response.body())); 26 | result.setWrapedResponse(response); 27 | } 28 | 29 | return result; 30 | } 31 | 32 | protected final ServerResponse convert(@Nullable Request request, IOException e) { 33 | ServerResponse result = new ServerResponse<>(); 34 | if (request != null) { 35 | result.setSuccessufl(false); 36 | result.setHeaders(request.headers()); 37 | result.setException(e); 38 | result.setWrapedRequest(request); 39 | } 40 | return result; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /gists/model/volley/cache-image-loader.md: -------------------------------------------------------------------------------- 1 | ### Volley: CacheImageLoader 2 | 3 | There are cases when you need to clean your memory. In [Volley Request Manager][1] I used `fields` to save cache references. There is more practical solution, just create a wrapper for `ImageLoader` : 4 | 5 | **Usage** 6 | 7 | ```java 8 | CacheImageLoader loader = ... // init loader 9 | 10 | loader.getMemoryCache().remove(url); // remove item by key 11 | loader.getMemoryCache().evictAll(); // remove all 12 | 13 | loader.getDiskCache().remove(url); // remove item by key 14 | loader.getDiskCache().clear(); // remove all 15 | ``` 16 | 17 | **Wrapper sources :** 18 | 19 | 20 | ```java 21 | public class CacheImageLoader extends ImageLoader { 22 | 23 | /** 24 | * Constructs a new ImageLoader. 25 | * 26 | * @param queue The RequestQueue to use for making image requests. 27 | * @param imageCache The cache to use as an L1 cache. 28 | */ 29 | 30 | private final MemoryCache mMemoryCache; 31 | private final Cache mDiskCache; 32 | 33 | public CacheImageLoader(RequestQueue queue, MemoryCache memoryCache) { 34 | super(queue, memoryCache); 35 | mMemoryCache = memoryCache; 36 | mDiskCache = queue.getCache(); 37 | } 38 | 39 | public MemoryCache getMemoryCache() { 40 | return mMemoryCache; 41 | } 42 | public Cache getDiskCache() { 43 | return mDiskCache; 44 | } 45 | } 46 | ``` 47 | 48 | [1]: https://github.com/yakivmospan/volley-request-manager 49 | -------------------------------------------------------------------------------- /gists/model/localparser/parse/XmlParser.java: -------------------------------------------------------------------------------- 1 | import org.xml.sax.InputSource; 2 | import org.xml.sax.SAXException; 3 | import org.xml.sax.XMLReader; 4 | 5 | import android.support.annotation.NonNull; 6 | import android.support.annotation.Nullable; 7 | 8 | import java.io.IOException; 9 | import java.io.InputStream; 10 | 11 | import javax.xml.parsers.ParserConfigurationException; 12 | import javax.xml.parsers.SAXParser; 13 | import javax.xml.parsers.SAXParserFactory; 14 | 15 | /** 16 | * Created by Yakiv M. on 09.02.2015. 17 | */ 18 | public class XmlParser implements ParseMethod { 19 | 20 | private final XmlHandler mHandler; 21 | 22 | public XmlParser(@NonNull XmlHandler handler) { 23 | mHandler = handler; 24 | } 25 | 26 | @Nullable 27 | @Override 28 | public R parse(@Nullable InputStream source) { 29 | if(source == null){ 30 | return null; 31 | } 32 | 33 | final SAXParserFactory spf = SAXParserFactory.newInstance(); 34 | final SAXParser saxParser; 35 | try { 36 | saxParser = spf.newSAXParser(); 37 | 38 | final XMLReader xmlReader = saxParser.getXMLReader(); 39 | xmlReader.setContentHandler(mHandler); 40 | 41 | xmlReader.parse(new InputSource(source)); 42 | return mHandler.getResult(); 43 | } catch (ParserConfigurationException | IOException | SAXException e) { 44 | L.e(e.getMessage()); 45 | return null; 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /gists/sample/battery-change-receiver.md: -------------------------------------------------------------------------------- 1 | **Usage** 2 | ```java 3 | private BatteryChangeReceiver mBatteryChangeReceiver; 4 | 5 | @Override 6 | protected void onCreate(Bundle savedInstanceState) { 7 | super.onCreate(savedInstanceState); 8 | 9 | mBatteryChangeReceiver = new BatteryChangeReceiver(getBaseContext()); 10 | mBatteryChangeReceiver.register(); 11 | } 12 | @Override 13 | protected void onDestroy() { 14 | if(mBatteryChangeReceiver != null){ 15 | mBatteryChangeReceiver.unRegister(); 16 | } 17 | super.onDestroy(); 18 | } 19 | ``` 20 | 21 | 22 | **BatteryChangeReceiver.java** 23 | ```java 24 | import android.content.BroadcastReceiver; 25 | import android.content.Context; 26 | import android.content.Intent; 27 | import android.content.IntentFilter; 28 | import android.support.annotation.NonNull; 29 | 30 | public class BatteryChangeReceiver 31 | extends BroadcastReceiver { 32 | 33 | private Context mContext; 34 | 35 | public BatteryChangeReceiver(@NonNull Context context) { 36 | mContext = context; 37 | } 38 | 39 | @Override 40 | public void onReceive(Context context, Intent intent) { 41 | int currentBatteryLevel = intent.getIntExtra("level", 0); 42 | if (currentBatteryLevel <= 50) { 43 | 44 | } 45 | } 46 | 47 | public void register(){ 48 | mContext.registerReceiver(this, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); 49 | } 50 | 51 | public void unRegister(){ 52 | mContext.unregisterReceiver(this); 53 | } 54 | } 55 | ``` 56 | -------------------------------------------------------------------------------- /gists/adapter/SimpleAdapter.java: -------------------------------------------------------------------------------- 1 | public class SimpleAdapter 2 | extends BaseAdapter { 3 | 4 | private List mData; 5 | private LayoutInflater mInflater; 6 | 7 | public SimpleAdapter(Context context, List data) { 8 | mInflater = LayoutInflater.from(context); 9 | mData = data; 10 | } 11 | 12 | @Override 13 | public int getCount() { 14 | return mData.size(); 15 | } 16 | 17 | @Override 18 | public Object getItem(int position) { 19 | return this.mData.get(position); 20 | } 21 | 22 | @Override 23 | public long getItemId(int position) { 24 | return position; 25 | } 26 | 27 | public View getView(int position, View convertView, ViewGroup parent) { 28 | ViewHolder holder = null; 29 | 30 | if (convertView == null) { 31 | holder = new ViewHolder(); 32 | convertView = mInflater.inflate(R.layout.layoutId, parent, false); 33 | 34 | holder.view = convertView.findViewById(R.id.viewId); 35 | convertView.setTag(holder); 36 | } else { 37 | holder = (ViewHolder) convertView.getTag(); 38 | } 39 | 40 | return convertView; 41 | } 42 | 43 | public void setData(List data) { 44 | mData = data; 45 | notifyDataSetChanged(); 46 | } 47 | 48 | public void addData(List data) { 49 | mData.addAll(data); 50 | notifyDataSetChanged(); 51 | } 52 | 53 | private static class ViewHolder { 54 | View view; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /gists/model/okhttp/okwrapper/RequestManager.java: -------------------------------------------------------------------------------- 1 | import com.squareup.okhttp.Cache; 2 | import com.squareup.okhttp.OkHttpClient; 3 | 4 | import android.content.Context; 5 | import android.support.annotation.NonNull; 6 | 7 | import java.io.IOException; 8 | import java.util.concurrent.TimeUnit; 9 | 10 | public class RequestManager { 11 | 12 | private static RequestManager mInstance; 13 | private static OkHttpClient mClient; 14 | 15 | private RequestManager(@NonNull Context context) { 16 | mClient = new OkHttpClient(); 17 | mClient.setReadTimeout(1, TimeUnit.SECONDS); 18 | mClient.setWriteTimeout(1, TimeUnit.SECONDS); 19 | mClient.setConnectTimeout(1, TimeUnit.SECONDS); 20 | 21 | int cacheSize = 10 * 1024 * 1024; // 10 MiB 22 | try { 23 | Cache cache = new Cache(context.getCacheDir(), cacheSize); 24 | mClient.setCache(cache); 25 | } catch (IOException e) { 26 | L.e(e.toString()); 27 | } 28 | } 29 | 30 | public static synchronized void initializeWith(@NonNull Context context) { 31 | if (mInstance == null) { 32 | mInstance = new RequestManager(context); 33 | } 34 | } 35 | 36 | public static synchronized OkHttpClient client() { 37 | if (mInstance == null) { 38 | throw new IllegalStateException(RequestManager.class.getSimpleName() + 39 | " is not initialized, call initialize() method first."); 40 | } 41 | return mInstance.getClient(); 42 | } 43 | 44 | private OkHttpClient getClient() { 45 | return mClient; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /gists/model/localparser/parse/JsonParser.java: -------------------------------------------------------------------------------- 1 | import android.support.annotation.NonNull; 2 | import android.support.annotation.Nullable; 3 | 4 | import java.io.BufferedReader; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.io.InputStreamReader; 8 | 9 | /** 10 | * Created by Yakiv M. on 09.02.2015. 11 | */ 12 | public class JsonParser implements ParseMethod { 13 | 14 | private final JsonHandler mHandler; 15 | 16 | public JsonParser(@NonNull JsonHandler handler) { 17 | mHandler = handler; 18 | } 19 | 20 | @Nullable 21 | @Override 22 | public R parse(@Nullable InputStream source) { 23 | if(source == null){ 24 | return null; 25 | } 26 | 27 | String js = convertStreamToString(source); 28 | if (js != null) { 29 | mHandler.parse(js); 30 | } 31 | 32 | return mHandler.getResult(); 33 | } 34 | 35 | private String convertStreamToString(InputStream is) { 36 | BufferedReader reader = new BufferedReader(new InputStreamReader(is)); 37 | StringBuilder sb = new StringBuilder(256); 38 | 39 | String line = null; 40 | try { 41 | while ((line = reader.readLine()) != null) { 42 | sb.append(line + "\n"); 43 | } 44 | } catch (IOException e) { 45 | e.printStackTrace(); 46 | } finally { 47 | try { 48 | is.close(); 49 | } catch (IOException e) { 50 | e.printStackTrace(); 51 | } 52 | } 53 | return sb.toString(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /gists/view/map/TouchableSupportMapFragment.java: -------------------------------------------------------------------------------- 1 | package fr.go_detect.godetect.view.map; 2 | 3 | import com.google.android.gms.maps.SupportMapFragment; 4 | 5 | import android.os.Bundle; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | 10 | import static android.view.View.OnTouchListener; 11 | 12 | /** 13 | * Created by Yakiv M. on 23.04.2015. 14 | */ 15 | public class TouchableSupportMapFragment extends SupportMapFragment { 16 | 17 | private View mOriginalContentView; 18 | private TouchableFrameLayout mTouchView; 19 | 20 | @Override 21 | public View onCreateView(LayoutInflater inflater, ViewGroup parent, Bundle savedInstanceState) { 22 | mOriginalContentView = super.onCreateView(inflater, parent, savedInstanceState); 23 | 24 | mTouchView = new TouchableFrameLayout(getActivity()); 25 | mTouchView.addView(mOriginalContentView); 26 | 27 | return mTouchView; 28 | } 29 | 30 | @Override 31 | public void onDestroyView() { 32 | super.onDestroyView(); 33 | 34 | mOriginalContentView = null; 35 | mTouchView = null; 36 | } 37 | 38 | @Override 39 | public View getView() { 40 | return mOriginalContentView; 41 | } 42 | 43 | public void addOnMapTouchListener(OnTouchListener listener) { 44 | if(mTouchView != null) { 45 | mTouchView.addOnTouchListener(listener); 46 | } 47 | } 48 | 49 | public void removeOnMapTouchListener(OnTouchListener listener) { 50 | if(mTouchView != null) { 51 | mTouchView.removeOnTouchListener(listener); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /gists/view/map/TouchableFrameLayout.java: -------------------------------------------------------------------------------- 1 | package fr.go_detect.godetect.view.map; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | import android.view.MotionEvent; 6 | import android.widget.FrameLayout; 7 | 8 | import java.util.ArrayList; 9 | import java.util.List; 10 | 11 | /** 12 | * Created by Yakiv M. on 23.04.2015. 13 | */ 14 | public class TouchableFrameLayout extends FrameLayout { 15 | 16 | private List mTouchListeners = new ArrayList<>(); 17 | 18 | public TouchableFrameLayout(Context context) { 19 | super(context); 20 | } 21 | public TouchableFrameLayout(Context context, AttributeSet attrs) { 22 | super(context, attrs); 23 | } 24 | public TouchableFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) { 25 | super(context, attrs, defStyleAttr); 26 | } 27 | public TouchableFrameLayout(Context context, AttributeSet attrs, int defStyleAttr, 28 | int defStyleRes) { 29 | super(context, attrs, defStyleAttr, defStyleRes); 30 | } 31 | 32 | @Override 33 | public boolean dispatchTouchEvent(MotionEvent ev) { 34 | for (OnTouchListener listener : mTouchListeners) { 35 | listener.onTouch(this, ev); 36 | } 37 | 38 | return super.dispatchTouchEvent(ev); 39 | } 40 | 41 | public void addOnTouchListener(OnTouchListener listener) { 42 | if(listener != null) { 43 | mTouchListeners.add(listener); 44 | } 45 | } 46 | 47 | public void removeOnTouchListener(OnTouchListener listener) { 48 | if(listener != null) { 49 | mTouchListeners.remove(listener); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /gists/adapter/SimplePagerAdapter.java: -------------------------------------------------------------------------------- 1 | import android.content.Context; 2 | import android.support.v4.view.PagerAdapter; 3 | import android.view.Gravity; 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 fr.go_detect.godetect.R; 11 | 12 | public class SimplePagerAdapter 13 | extends PagerAdapter { 14 | 15 | private int[] mData; 16 | private LayoutInflater mInflater; 17 | 18 | public TextSliderAdapter(Context context, int... data) { 19 | mInflater = LayoutInflater.from(context); 20 | mData = data; 21 | } 22 | 23 | @Override 24 | public int getCount() { 25 | return mData.length; 26 | } 27 | 28 | @Override 29 | public boolean isViewFromObject(View view, Object object) { 30 | return view == object; 31 | } 32 | 33 | @Override 34 | public Object instantiateItem(ViewGroup container, int position) { 35 | TextView view = new TextView(mInflater.getContext()); 36 | view.setLayoutParams(new ViewGroup.LayoutParams( 37 | ViewGroup.LayoutParams.MATCH_PARENT, 38 | ViewGroup.LayoutParams.MATCH_PARENT 39 | )); 40 | 41 | view.setTextAppearance(mInflater.getContext(), R.style.Set_Font_Here); 42 | view.setGravity(Gravity.CENTER); 43 | view.setText(getItem(position)); 44 | 45 | int childCount = container.getChildCount(); 46 | container.addView(view, childCount > position ? position : childCount); 47 | 48 | container.addView(view, 0); 49 | return view; 50 | } 51 | 52 | @Override 53 | public void destroyItem(ViewGroup container, int position, Object object) { 54 | container.removeView((View) object); 55 | } 56 | 57 | public int getItem(int position) { 58 | return this.mData[position]; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /gists/view/typeface-spannable.md: -------------------------------------------------------------------------------- 1 | Usage 2 | 3 | ```java 4 | TextView txt = (TextView) findViewById(R.id.custom_fonts); 5 | txt.setTextSize(30); 6 | 7 | Typeface font = Typeface.createFromAsset(getAssets(), "Akshar.ttf"); 8 | Typeface font2 = Typeface.createFromAsset(getAssets(), "bangla.ttf"); 9 | SpannableStringBuilder SS = new SpannableStringBuilder("???????????"); 10 | SS.setSpan (new CustomTypefaceSpan("", font2), 0, 4,Spanned.SPAN_EXCLUSIVE_INCLUSIVE); 11 | SS.setSpan (new CustomTypefaceSpan("", font), 4, 11,Spanned.SPAN_EXCLUSIVE_INCLUSIVE); 12 | txt.setText(SS); 13 | ``` 14 | 15 | CustomTypefaceSpan.java 16 | ```java 17 | import android.graphics.Paint; 18 | import android.graphics.Typeface; 19 | import android.text.TextPaint; 20 | import android.text.style.TypefaceSpan; 21 | 22 | public class CustomTypefaceSpan extends TypefaceSpan { 23 | private final Typeface newType; 24 | 25 | public CustomTypefaceSpan(String family, Typeface type) { 26 | super(family); 27 | newType = type; 28 | } 29 | 30 | @Override 31 | public void updateDrawState(TextPaint ds) { 32 | applyCustomTypeFace(ds, newType); 33 | } 34 | 35 | @Override 36 | public void updateMeasureState(TextPaint paint) { 37 | applyCustomTypeFace(paint, newType); 38 | } 39 | 40 | private static void applyCustomTypeFace(Paint paint, Typeface tf) { 41 | int oldStyle; 42 | Typeface old = paint.getTypeface(); 43 | if (old == null) { 44 | oldStyle = 0; 45 | } else { 46 | oldStyle = old.getStyle(); 47 | } 48 | 49 | int fake = oldStyle & ~tf.getStyle(); 50 | if ((fake & Typeface.BOLD) != 0) { 51 | paint.setFakeBoldText(true); 52 | } 53 | 54 | if ((fake & Typeface.ITALIC) != 0) { 55 | paint.setTextSkewX(-0.25f); 56 | } 57 | 58 | paint.setTypeface(tf); 59 | } 60 | } 61 | ``` -------------------------------------------------------------------------------- /gists/utils/NetworkUtils.java: -------------------------------------------------------------------------------- 1 | 2 | import android.annotation.TargetApi; 3 | import android.content.Context; 4 | import android.net.ConnectivityManager; 5 | import android.net.Network; 6 | import android.net.NetworkInfo; 7 | import android.os.Build; 8 | import android.support.annotation.NonNull; 9 | 10 | 11 | public class NetworkUtils { 12 | 13 | public static boolean isConnected(@NonNull Context context) { 14 | ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 15 | NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); 16 | return (networkInfo != null && networkInfo.isConnected()); 17 | } 18 | 19 | public static boolean isWifiConnected(@NonNull Context context) { 20 | return isConnected(context, ConnectivityManager.TYPE_WIFI); 21 | } 22 | 23 | public static boolean isMobileConnected(@NonNull Context context) { 24 | return isConnected(context, ConnectivityManager.TYPE_MOBILE); 25 | } 26 | 27 | private static boolean isConnected(@NonNull Context context, int type) { 28 | ConnectivityManager connMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 29 | if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { 30 | NetworkInfo networkInfo = connMgr.getNetworkInfo(type); 31 | return networkInfo != null && networkInfo.isConnected(); 32 | } else { 33 | return isConnected(connMgr, type); 34 | } 35 | } 36 | 37 | @TargetApi(Build.VERSION_CODES.LOLLIPOP) 38 | private static boolean isConnected(@NonNull ConnectivityManager connMgr, int type) { 39 | Network[] networks = connMgr.getAllNetworks(); 40 | NetworkInfo networkInfo; 41 | for (Network mNetwork : networks) { 42 | networkInfo = connMgr.getNetworkInfo(mNetwork); 43 | if (networkInfo != null && networkInfo.getType() == type && networkInfo.isConnected()) { 44 | return true; 45 | } 46 | } 47 | return false; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /gists/view/custom-actionbar-title.md: -------------------------------------------------------------------------------- 1 | ### Important: 2 | 3 | - Use R.layout.ben_toolbar_simple_title if you have menu items in layout, or doesn't have any buttons at all 4 | - Use R.layout.ben_toolbar_margin_title if you have only one button in left corner (it could be back button for e.g) 5 | 6 | **Activity.java** 7 | ```java 8 | public void initActionBar() { 9 | ActionBar supportActionBar = getSupportActionBar(); 10 | supportActionBar.setDisplayShowTitleEnabled(false); 11 | supportActionBar.setDisplayHomeAsUpEnabled(true); 12 | supportActionBar.setDisplayShowCustomEnabled(true); 13 | 14 | supportActionBar.setCustomView(R.layout.toolbar_simple_title);//have no margin 15 | supportActionBar.setCustomView(R.layout.toolbar_margin_title);//have righth margin 16 | 17 | TextView toolbarTitle = (TextView) supportActionBar.getCustomView().findViewById( 18 | R.id.toolbarTitle 19 | ); 20 | toolbarTitle.setText(R.string.share); 21 | 22 | //supportActionBar.setBackgroundDrawable(); 23 | //... 24 | } 25 | ``` 26 | 27 | **toolbar_margin_title.xml** 28 | ```xml 29 | 39 | 40 | ``` 41 | 42 | **toolbar_simple_title.xml** 43 | ```xml 44 | 53 | 54 | ``` 55 | -------------------------------------------------------------------------------- /gists/model/okhttp/okwrapper/ServerResponse.java: -------------------------------------------------------------------------------- 1 | import com.squareup.okhttp.Headers; 2 | import com.squareup.okhttp.Request; 3 | import com.squareup.okhttp.Response; 4 | 5 | import java.io.IOException; 6 | import java.net.ConnectException; 7 | import java.net.UnknownHostException; 8 | 9 | /** 10 | * Created by Yakiv M. on 09.02.2015. 11 | */ 12 | public class ServerResponse { 13 | private int mCode; 14 | private IOException mException; 15 | 16 | private boolean mIsSuccessufl; 17 | private SuccessResult mSuccessResult; 18 | 19 | private Headers mHeaders; 20 | 21 | private Response mWrapedResponse; 22 | 23 | private Request mWrapedRequest; 24 | 25 | public boolean isConnectionIssue() { 26 | return mException instanceof ConnectException || mException instanceof UnknownHostException; 27 | } 28 | 29 | public int getCode() { 30 | return mCode; 31 | } 32 | 33 | public void setCode(int code) { 34 | mCode = code; 35 | } 36 | 37 | public IOException getException() { 38 | return mException; 39 | } 40 | 41 | public void setException(IOException exception) { 42 | mException = exception; 43 | } 44 | 45 | public SuccessResult getSuccessResult() { 46 | return mSuccessResult; 47 | } 48 | 49 | public void setSuccessResult(SuccessResult successResult) { 50 | mSuccessResult = successResult; 51 | } 52 | 53 | public Headers getHeaders() { 54 | return mHeaders; 55 | } 56 | 57 | public void setHeaders(Headers headers) { 58 | mHeaders = headers; 59 | } 60 | 61 | public boolean isSuccessufl() { 62 | return mIsSuccessufl; 63 | } 64 | 65 | public void setSuccessufl(boolean isSuccessufl) { 66 | mIsSuccessufl = isSuccessufl; 67 | } 68 | 69 | public Response getWrapedResponse() { 70 | return mWrapedResponse; 71 | } 72 | 73 | public void setWrapedResponse(Response wrapedResponse) { 74 | mWrapedResponse = wrapedResponse; 75 | } 76 | 77 | public Request getWrapedRequest() { 78 | return mWrapedRequest; 79 | } 80 | 81 | public void setWrapedRequest(Request wrapedRequest) { 82 | mWrapedRequest = wrapedRequest; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /gists/utils/app-state-tracker.md: -------------------------------------------------------------------------------- 1 | ```java 2 | import java.util.ArrayList; 3 | 4 | /** 5 | * Tracks whenever application goes into background and foreground state. 6 | * 7 | *

Add {@link OnStateChangeListener} and call {@code onActivityStart(), 8 | * onActivityStop()} and {@code onActivityCreate()} in each of your Activities. Best practice for 9 | * API < 14 is to create BaseActivity and do it there. In API >= 14 you can register {@link 10 | * android.app.Application.ActivityLifecycleCallbacks} in {@link android.app.Application} and match 11 | * lifecycle call there. 12 | */ 13 | public class AppStateTracker { 14 | 15 | private static AppStateTracker sInstance; 16 | 17 | private ArrayList mListeners = new ArrayList<>(); 18 | 19 | private boolean mIsInForeground; 20 | private int mForegroundScreensCount; 21 | 22 | private AppStateTracker() { 23 | } 24 | 25 | public static AppStateTracker getInstance() { 26 | if (sInstance == null) { 27 | synchronized (AppStateTracker.class) { 28 | if (sInstance == null) { 29 | sInstance = new AppStateTracker(); 30 | } 31 | } 32 | } 33 | return sInstance; 34 | } 35 | 36 | public void onActivityStart() { 37 | mForegroundScreensCount++; 38 | checkStateChange(); 39 | } 40 | 41 | public void onActivityStop() { 42 | mForegroundScreensCount--; 43 | checkStateChange(); 44 | } 45 | 46 | private void checkStateChange() { 47 | if (mForegroundScreensCount > 0 && !mIsInForeground) { 48 | // app goes into foreground 49 | for (OnStateChangeListener listener : mListeners) { 50 | mIsInForeground = true; 51 | listener.onForeground(); 52 | } 53 | } else if (mForegroundScreensCount == 0 && mIsInForeground) { 54 | // app goes into background 55 | for (OnStateChangeListener listener : mListeners) { 56 | mIsInForeground = false; 57 | listener.onBackground(); 58 | } 59 | } 60 | } 61 | 62 | public void addOnStateChangeListener(OnStateChangeListener listener) { 63 | mListeners.add(listener); 64 | } 65 | 66 | public void removeOnStateChangeListener(OnStateChangeListener listener) { 67 | mListeners.remove(listener); 68 | } 69 | 70 | public void clearOnStateChangeListeners() { 71 | mListeners.clear(); 72 | } 73 | 74 | public interface OnStateChangeListener { 75 | void onForeground(); 76 | void onBackground(); 77 | } 78 | 79 | } 80 | ``` 81 | -------------------------------------------------------------------------------- /articles/pebble/Pebble. Little Helper.md: -------------------------------------------------------------------------------- 1 | ![Thumbnail](/assets/images/articles/pebble-little-helper.png) 2 | 3 | ### Pebble: Little Helper 4 | 5 | Day by day technology is growing up and is doing this really fast. Of course it didn't forget about wearable devices like [smartwatches][1]. I was always thinking that smartwatch is not the best idea. Who wants watch that need to be charged every day? But [Pebble][2] made me to believe in them. 6 | 7 | ![Pebble Icon](/assets/images/articles/pebble-icon.jpg) 8 | 9 | ### Why Pebble ? 10 | 11 | - Simple in use 12 | - Pixel e-paper display 13 | - Big applications market 14 | - Battery - you can use it all week and don't bother about charge level. 15 | - Design - it looks really impressive. A lot of customization are allowed. 16 | - Cross platforming - works with Android and iOS 17 | - A lot of possibilities for developers 18 | 19 | ![Pebble Icon 2](/assets/images/articles/pebble-icon-2.jpg) 20 | 21 | ### Usage 22 | 23 | - Alarm manger 24 | - Read messages 25 | - Control your calls 26 | - Control your music tracks 27 | - Play games 28 | - You can use it as speedometer while running or riding or even skiing 29 | 30 | Lets look closer : 31 | 32 | - I don't like to carry a lot of staff with me. Thats why I use only my phone to listen music or read books. And every day in bus, metro or while riding the bike I was needed to take it out from pocket every time I wanted another track. That was anoing. And now all I need is to touch my hand. 33 | - If you love skiing like I do than you know how hard is to get your phone from pocket at the mountain. And with Pebble you can even track your run statistic without doing that. 34 | 35 | 36 | Pebble opens the door into the world of Comfort and new Possibilities. 37 | 38 | ![Pebble Icon Bike](/assets/images/articles/pebble-icon-bike.jpg) 39 | 40 | ### Development 41 | 42 | To start developing for Pebble you simple need to : 43 | 44 | - Meet Pebble Developers [site][3] 45 | - Download [Pebble SDK][4] 46 | - Download Pebble application from Market ([Android][5], [iOS][6]) 47 | - Go throw some samples on [GitHub][7] 48 | 49 | Meet any troubles? You can always take care of them here : 50 | 51 | - [Pebble Forum][8] 52 | - [Stack Overflow][9] 53 | 54 | 55 | [1]: http://en.wikipedia.org/wiki/Smartwatch 56 | [2]: http://en.wikipedia.org/wiki/Pebble_%28watch%29 57 | [3]: https://developer.getpebble.com/ 58 | [4]: https://developer.getpebble.com/2/getting-started/ 59 | [5]: https://play.google.com/store/apps/details?id=com.getpebble.android 60 | [6]: http://www.apple.com/itunes/affiliates/download/ 61 | [7]: https://github.com/search?q=pebble&ref=cmdform 62 | [8]: https://forums.getpebble.com/categories/developer-discussion 63 | [9]: http://stackoverflow.com/questions/tagged/pebble-watch 64 | -------------------------------------------------------------------------------- /gists/widget/simple-implementation.md: -------------------------------------------------------------------------------- 1 | ### Widget: Simple Implementation 2 | 3 | Snippent shows simple implementation of android widget that can recieve custom intents. Also shows how to update widget 4 | 5 | **Send custom intent to widget:** 6 | ```java 7 | //Note. Don't use LocalBroadcastManager to send intents to widget, it won't work 8 | context.sendBroadcast(new Intent(Widget.CUSTOM_ACTION)); 9 | ``` 10 | 11 | **Widget**: 12 | ```java 13 | import android.app.PendingIntent; 14 | import android.appwidget.AppWidgetManager; 15 | import android.appwidget.AppWidgetProvider; 16 | import android.content.ComponentName; 17 | import android.content.Context; 18 | import android.content.Intent; 19 | import android.widget.RemoteViews; 20 | 21 | public class Widget extends AppWidgetProvider { 22 | 23 | public static final String CUSTOM_ACTION = "com.your.package.CUSTOM_ACTION"; 24 | 25 | @Override 26 | public void onUpdate(final Context context, AppWidgetManager appWidgetManager, 27 | int[] appWidgetIds) { 28 | for (int i = 0; i < appWidgetIds.length; i++) { 29 | appWidgetManager.updateAppWidget(appWidgetIds[i], getRemoteViews(context)); 30 | } 31 | } 32 | 33 | @Override 34 | public void onReceive(Context context, Intent intent) { 35 | super.onReceive(context, intent); 36 | String action = intent.getAction(); 37 | 38 | if (CUSTOM_ACTION.equals(action)) { 39 | AppWidgetManager widgetManager = AppWidgetManager.getInstance(context); 40 | ComponentName component = new ComponentName( 41 | context.getPackageName(), Widget.class.getName() 42 | ); 43 | 44 | RemoteViews views = getRemoteViews(context); 45 | widgetManager.updateAppWidget(component, views); 46 | } 47 | } 48 | 49 | private RemoteViews getRemoteViews(Context context) { 50 | Intent intent = new Intent(context, MainActivity.class); 51 | PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); 52 | 53 | RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout); 54 | views.setOnClickPendingIntent(R.id.viewId, pendingIntent); 55 | views.setTextViewText(R.id.viewId, "Some text"); 56 | return views; 57 | } 58 | } 59 | 60 | ``` 61 | 62 | **AndroidManifest:** 63 | ```xml 64 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 77 | 78 | 79 | ``` 80 | -------------------------------------------------------------------------------- /assets/css/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 15px; 3 | font-family: 'Source Sans Pro', sans-serif; 4 | font-size: 17px; 5 | color: #5b6064; 6 | font-weight: 400; 7 | background-color: #FDFDFD; 8 | } 9 | 10 | h1 { 11 | font-family: 'Source Sans Pro', sans-serif; 12 | font-weight: 300; 13 | font-size: 64px; 14 | color: #333; 15 | } 16 | 17 | h2 { 18 | margin-top: 50px; 19 | margin-bottom: 25px; 20 | font-family: 'Source Sans Pro', sans-serif; 21 | font-weight: 400; 22 | font-size: 22px; 23 | color: #222; 24 | } 25 | 26 | h4 { 27 | margin: 30px 0 15px 0; 28 | font-family: 'Source Sans Pro', sans-serif; 29 | font-weight: 300; 30 | font-size: 22px; 31 | } 32 | 33 | h5 { 34 | margin: 30px 0 15px 0; 35 | font-family: 'Source Sans Pro', sans-serif; 36 | font-weight: 300; 37 | font-size: 20px; 38 | } 39 | 40 | span.tag { 41 | background-color: #e0eaf1; 42 | color: #3e6d8e; 43 | vertical-align: baseline; 44 | white-space: pre-wrap; 45 | } 46 | 47 | p { 48 | margin-bottom: 10px; 49 | float: none; 50 | } 51 | 52 | p.tag { 53 | margin-top: 10px; 54 | margin-bottom: 5px; 55 | } 56 | 57 | a { 58 | color: #33B5E5; 59 | /*font-style: italic;*/ 60 | text-decoration: none; 61 | } 62 | 63 | a:hover { 64 | text-decoration: underline; 65 | color: #33B5E5; 66 | } 67 | 68 | a:active { 69 | color: #FFFFFF; 70 | background-color: #33B5E5; 71 | text-decoration: none; 72 | } 73 | 74 | li { 75 | margin: 0 0 5px; 76 | } 77 | 78 | p.blue { 79 | margin-bottom: 10px; 80 | float: none; 81 | color: #33B5E5; 82 | } 83 | 84 | p.intro { 85 | margin: 20px 0 20px 0; 86 | font-size: 19px; 87 | font-weight: 300; 88 | } 89 | 90 | hr { 91 | border: 0; 92 | border-top: 1px solid #eee; 93 | margin-top: 15px; 94 | margin-bottom: 15px; 95 | } 96 | 97 | .date { 98 | color: #999; 99 | font-size: 22px; 100 | font-weight: 300; 101 | float: left; 102 | } 103 | 104 | .codeblock { 105 | font-family: Inconsolata, monospace; 106 | font-weight: 400; 107 | padding: 2px 4px; 108 | color: #333; 109 | white-space: pre-line; 110 | background-color: #f7f7f9; 111 | border: 1px solid #e1e1e8; 112 | margin: 15px 15px; 113 | float: none; 114 | } 115 | 116 | .code { 117 | font-family: Inconsolata, monospace; 118 | font-weight: 400; 119 | } 120 | 121 | .container { 122 | max-width: 900px; 123 | margin-left: auto; 124 | margin-right: auto; 125 | } 126 | 127 | p.article-list { 128 | margin: 20px 0 20px 0; 129 | font-size: 20px; 130 | font-weight: 300; 131 | font-style: italic; 132 | } 133 | 134 | #share-buttons img { 135 | width: 35px; 136 | padding: 5px; 137 | border: 0; 138 | display: inline; 139 | } 140 | 141 | img.avatar { 142 | float: right; 143 | border: 1px solid #999; 144 | width: 128px; 145 | height: 128px; 146 | } 147 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Resume - Yakiv Mospan 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 |

Yakiv Mospan

20 | 21 |
22 |

Android Software Developer

23 | 24 | 25 |
26 | 27 | 28 | 29 | Facebook 30 | 31 | 32 | 33 | Twitter 34 | 35 | 36 | 37 | Google 38 | 39 |
40 |
41 | 42 |
43 | 44 |
45 | 46 |

E-Mail: yakiv.mospan [at] gmail [dot] com

47 | 48 |

Skype: yakiv.mospan

49 | 50 |

About me

51 | 52 |

53 | I have loved video games since I was a child. Beautiful and creative worlds and histories, amazing animation and charismatic characters - I always wanted to create something like that. Games pushed me to become a developer.

54 | 55 |

56 | One day I will meet game industry but for today I’m successful Android Developer at Lemberg Solutions Limited. Love my job. Working hard to become better. And, of course, not forgetting to make some fun.

57 | 58 |

Technologies

59 | 60 |

Like

61 | 62 | Java 63 | Android 64 | SQL 65 | XML 66 | JSON 67 | Rest 68 | Git 69 | SVN 70 | Android Studio 71 | Intellij Idea 72 | 73 |

Dislike

74 | 75 | Assembler 76 | C 77 | C++ 78 | Objective-C 79 | Eclipse 80 | 81 |
82 | 83 | 84 | 85 | 86 | 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /gists/model/okhttp/okwrapper.md: -------------------------------------------------------------------------------- 1 | ### Model: okhttp wrapper 2 | 3 | Snippet shows how to use [okwrapper](/gists/model/okhttp/okwrapper) 4 | 5 | - Init request manager 6 | 7 | ```java 8 | public class App extends Application { 9 | @Override 10 | public void onCreate() { 11 | //.. 12 | RequestManager.initializeWith(this); 13 | } 14 | } 15 | ``` 16 | - Create your API, class that will manage requests 17 | 18 | ```java 19 | public class ExampleApi extends AbsApi { 20 | //... 21 | } 22 | ``` 23 | 24 | - Use built in `AbsApi` help methods 25 | 26 | ```java 27 | public class ExampleApi extends AbsApi { 28 | public static ServerResponse> loadAllPeople () { 29 | //create request builder 30 | Request.Builder builder = new Request.Builder(); 31 | 32 | //add authorization 33 | builder.header("Authorization", Credentials.basic( 34 | "login", "password") 35 | ); 36 | 37 | //add headers 38 | builder.addHeader("App-Version", BuildConfig.VERSION_NAME); 39 | 40 | //add body 41 | FormEncodingBuilder bodyBuilder = new FormEncodingBuilder(); 42 | bodyBuilder.add("organization", organizationId); 43 | 44 | builder.post(bodyBuilder.build()); 45 | 46 | //add url 47 | builder.url(UrlFactory.createPeopleUrl()); 48 | 49 | //make sync call to the server 50 | //use callAsync() for async requests 51 | return call( 52 | //set client to be used for request 53 | RequestManager.client(), 54 | builder.build(), 55 | //choose result convert method 56 | //by default there are available 3 methods 57 | //JsonConverter, XmlConverter and StringConverter 58 | //you can create your own one by extending ConvertMethod 59 | new JsonConverter<>(new PeopleJsonHandler()) 60 | ); 61 | } 62 | } 63 | ``` 64 | 65 | - Separate your API requests in Commands 66 | 67 | ```java 68 | public class PeopleCommand extends AbsCommand> { 69 | 70 | @NonNull 71 | @Override 72 | public OkHttpClient createClient() { 73 | return RequestManager.client(); 74 | } 75 | 76 | @NonNull 77 | @Override 78 | public Request createRequest() { 79 | Request.Builder builder = new Request.Builder(); 80 | builder.header("Authorization", Credentials.basic( 81 | "login", "password") 82 | ); 83 | builder.addHeader("App-Version", BuildConfig.VERSION_NAME); 84 | FormEncodingBuilder bodyBuilder = new FormEncodingBuilder(); 85 | bodyBuilder.add("organization", organizationId); 86 | builder.post(bodyBuilder.build()); 87 | builder.url(UrlFactory.createPeopleUrl()); 88 | return builder.build(); 89 | } 90 | 91 | @NonNull 92 | @Override 93 | public ConvertMethod> createConvertMethod() { 94 | return new JsonConverter<>(new PeopleJsonHandler()); 95 | } 96 | 97 | @NonNull 98 | @Override 99 | public void onResponse(ServerResponse> response) { 100 | //operate with your result before finishing 101 | if (response.isSuccessufl()) { 102 | //.. 103 | } 104 | } 105 | } 106 | ``` 107 | 108 | - And simply use them in your API class 109 | ```java 110 | public class ExampleApi extends AbsApi { 111 | 112 | //... 113 | 114 | public static ServerResponse> loadAllPeople () { 115 | return call(new PeopleCommand()); 116 | } 117 | } 118 | ``` 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /articles/android/http/Volley Request Manager - Lite.md: -------------------------------------------------------------------------------- 1 | ![Header](/assets/images/articles/http-volley-request-manager-lite.png) 2 | 3 | ### Volley Request Manager - Lite 4 | 5 | [Full source code on github][1] 6 | 7 | In my [Volley Request Manager][2] article I've described model that covers a lot of stuff. But in practice you need only half of it or even less. So I've decided to create this version, that is : 8 | 9 | - Reusable 10 | - So simple as possible 11 | - With possibility to include HTTP Client and Image Loader or only one of them 12 | 13 | ### Description 14 | 15 | Library consists of two simple packages: **http** and **utils**. They are independent. 16 | 17 | **http** contains only two independent classes : 18 | 19 | - `ImageManager` - for image loading 20 | - `RequestManager` - for requests processing 21 | 22 | **utils** contains classes that will help you to create your own `Requests`, `Queues` or `ImageLoaders`. You can use them if you wish 23 | 24 | ### Usage 25 | 26 | Include [library][2] or just copy component that you need from **http** package in your project. 27 | 28 | ```java 29 | // init component for request processing 30 | RequestManager.initializeWith(getApplicationContext()); 31 | 32 | // create request 33 | Request request = new JsonObjectRequest( 34 | Request.Method.GET, 35 | "request url here", 36 | null, 37 | mListener, 38 | mErrorListener); 39 | 40 | // process request with default queue 41 | RequestManager.queue().add(request); 42 | ``` 43 | 44 | ```java 45 | // init component for image loading 46 | ImageManager.initializeWith(getApplicationContext()); 47 | 48 | // load image with default ImageLoader 49 | ImageManager.loader().get( 50 | "http://farm6.staticflickr.com/5475/10375875123_75ce3080c6_b.jpg", 51 | mImageListener); 52 | 53 | // load image with NetworkImageView 54 | NetworkImageView view = new NetworkImageView(context); 55 | 56 | view.setImageUrl( 57 | "http://farm6.staticflickr.com/5475/10375875123_75ce3080c6_b.jpg", 58 | ImageManager.loader()); // to use default ImageLoader 59 | ``` 60 | 61 | ### Tips 62 | 63 | - Create `HttpUtils` class to hold all your url, headers creation methods in one place 64 | 65 | ```java 66 | public class HttpUtils { 67 | 68 | public static String createTestUrl() { 69 | Uri.Builder uri = new Uri.Builder(); 70 | uri.scheme("http"); 71 | uri.authority("httpbin.org"); 72 | uri.path("get"); 73 | uri.appendQueryParameter("name", "Jon Doe"); 74 | uri.appendQueryParameter("age", "21"); 75 | 76 | return uri.build().toString(); 77 | } 78 | } 79 | ``` 80 | 81 | - Create `HttpFactory` class to hold all your reusable requests 82 | 83 | ```java 84 | public class HttpFactory { 85 | 86 | public static void createTestRequest(Response.Listener listener, 87 | Response.ErrorListener errorListener) { 88 | Request request = new JsonObjectRequest( 89 | Request.Method.GET, 90 | HttpUtils.createTestUrl(), 91 | null, 92 | listener, 93 | errorListener); 94 | RequestManager.queue().add(request); 95 | } 96 | 97 | public static void loadImageWithDefaultStub(String url, NetworkImageView view) { 98 | view.setDefaultImageResId(R.drawable.ic_launcher); 99 | view.setImageUrl( 100 | url, 101 | ImageManager.loader()); 102 | } 103 | } 104 | ``` 105 | 106 | [1]: https://github.com/yakivmospan/volley-request-manager-lite 107 | [2]: https://github.com/yakivmospan/yakivmospan/blob/master/articles/android/http/Volley%20Request%20Manager.md 108 | -------------------------------------------------------------------------------- /gists/model/okhttp/okwrapper/AbsApi.java: -------------------------------------------------------------------------------- 1 | import com.squareup.okhttp.Callback; 2 | import com.squareup.okhttp.OkHttpClient; 3 | import com.squareup.okhttp.Request; 4 | import com.squareup.okhttp.Response; 5 | 6 | import android.support.annotation.NonNull; 7 | import android.support.annotation.Nullable; 8 | 9 | import java.io.IOException; 10 | 11 | /** 12 | * Created by Yakiv M. on 09.02.2015. 13 | */ 14 | public class AbsApi { 15 | 16 | protected static ServerResponse call( 17 | @NonNull OkHttpClient client, 18 | @NonNull Request request, 19 | @NonNull ConvertMethod method) { 20 | ServerResponse result = new ServerResponse(); 21 | try { 22 | Response response = client.newCall(request).execute(); 23 | result = method.convert(response); 24 | } catch (IOException e) { 25 | L.d(e.toString()); 26 | result.setException(e); 27 | } 28 | 29 | return result; 30 | } 31 | 32 | protected static ServerResponse call(@NonNull AbsCommand command) { 33 | ServerResponse response = call( 34 | command.createClient(), command.createRequest(), command.createConvertMethod() 35 | ); 36 | command.onResponse(response); 37 | return response; 38 | } 39 | 40 | protected static void callAsync( 41 | @NonNull OkHttpClient client, @NonNull Request request, 42 | @NonNull ConvertMethod method, @Nullable RequestCallback callback) { 43 | client.newCall(request).enqueue(createCallback(method, callback)); 44 | } 45 | 46 | protected static void callAsync( 47 | @NonNull AbsCommand command, @Nullable RequestCallback callback) { 48 | command.createClient() 49 | .newCall(command.createRequest()) 50 | .enqueue(createCallback(command, callback)); 51 | } 52 | 53 | private static Callback createCallback( 54 | final AbsCommand command, final RequestCallback callback) { 55 | return new Callback() { 56 | @Override 57 | public void onFailure(Request request, IOException e) { 58 | ConvertMethod method = command.createConvertMethod(); 59 | ServerResponse serverResponse = method.convert(request, e); 60 | command.onResponse(serverResponse); 61 | 62 | if (callback != null) { 63 | callback.onResponse(serverResponse); 64 | } 65 | } 66 | 67 | @Override 68 | public void onResponse(Response response) throws IOException { 69 | ConvertMethod method = command.createConvertMethod(); 70 | ServerResponse serverResponse = method.convert(response); 71 | command.onResponse(serverResponse); 72 | 73 | if (callback != null) { 74 | callback.onResponse(serverResponse); 75 | } 76 | } 77 | }; 78 | } 79 | 80 | private static Callback createCallback( 81 | final ConvertMethod method, final RequestCallback callback) { 82 | return new Callback() { 83 | 84 | @Override 85 | public void onFailure(Request request, IOException e) { 86 | ServerResponse serverResponse = method.convert(request, e); 87 | 88 | if (callback != null) { 89 | callback.onResponse(serverResponse); 90 | } 91 | } 92 | 93 | @Override 94 | public void onResponse(Response response) throws IOException { 95 | ServerResponse serverResponse = method.convert(response); 96 | if (callback != null) { 97 | callback.onResponse(serverResponse); 98 | } 99 | } 100 | }; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /gists/view/drawable/color-sates-list-drawable.md: -------------------------------------------------------------------------------- 1 | **Usage**: 2 | 3 | ```java 4 | ascentColor = getAscentColor(); 5 | 6 | final Drawable unSelected = context.getResources().getDrawable( 7 | R.drawable.unselected 8 | ); 9 | 10 | final Drawable selected = context.getResources().getDrawable( 11 | R.drawable.tab_selected 12 | ); 13 | 14 | ColorStatesListDrawable result = new ColorStatesListDrawable(); 15 | 16 | result.addState( 17 | new int[]{android.R.attr.state_selected}, selected, 18 | DrawableUtil.getDirectColorFilter(ascentColor) 19 | ); 20 | 21 | result.addState( 22 | new int[]{android.R.attr.state_checked}, selected, 23 | DrawableUtil.getDirectColorFilter(ascentColor) 24 | ); 25 | 26 | result.addState( 27 | new int[]{android.R.attr.state_enabled}, unSelected, 28 | DrawableUtil.getDirectColorFilter(ascentColor) 29 | ); 30 | ``` 31 | 32 | **ColorStatesListDrawable.java** 33 | ```java 34 | import android.graphics.ColorFilter; 35 | import android.graphics.drawable.Drawable; 36 | import android.graphics.drawable.StateListDrawable; 37 | import android.util.StateSet; 38 | 39 | import java.util.ArrayList; 40 | import java.util.List; 41 | 42 | public class ColorStatesListDrawable extends StateListDrawable { 43 | 44 | private List mStates = new ArrayList(); 45 | 46 | public ColorStatesListDrawable() { 47 | super(); 48 | } 49 | 50 | @Override 51 | public ConstantState getConstantState() { 52 | return new ColorConstantState(super.getConstantState()); 53 | } 54 | 55 | @Override 56 | protected boolean onStateChange(int[] states) { 57 | State state = findState(states); 58 | if (state != null) { 59 | applyFilter(state); 60 | } else { 61 | clearColorFilter(); 62 | } 63 | 64 | return super.onStateChange(states); 65 | } 66 | 67 | public void addState(int[] stateSet, Drawable drawable, ColorFilter colorFilter) { 68 | super.addState(stateSet, drawable); 69 | mStates.add(new State(stateSet, drawable, colorFilter)); 70 | } 71 | 72 | @Override 73 | public void addState(int[] stateSet, Drawable drawable) { 74 | addState(stateSet, drawable, null); 75 | } 76 | 77 | void applyFilter(State state) { 78 | setColorFilter(state.colorFilter); 79 | } 80 | 81 | private State findState(int[] stateSet) { 82 | if (mStates != null) { 83 | for (int i = 0; i < mStates.size(); i++) { 84 | State state = mStates.get(i); 85 | if (StateSet.stateSetMatches(state.set, stateSet)) { 86 | return state; 87 | } 88 | } 89 | } 90 | return null; 91 | } 92 | 93 | static final class State { 94 | 95 | int[] set; 96 | Drawable drawable; 97 | ColorFilter colorFilter; 98 | 99 | State(int[] stateSet, Drawable drawable, ColorFilter colorFilter) { 100 | this.set = stateSet; 101 | this.drawable = drawable; 102 | this.colorFilter = colorFilter; 103 | } 104 | } 105 | 106 | public class ColorConstantState extends ConstantState { 107 | 108 | private ConstantState mConstantState; 109 | 110 | public ColorConstantState(ConstantState constantState) { 111 | mConstantState = constantState; 112 | } 113 | 114 | @Override 115 | public Drawable newDrawable() { 116 | ColorStatesListDrawable statesListDrawable = new ColorStatesListDrawable(); 117 | 118 | for (State state : mStates) { 119 | statesListDrawable.addState( 120 | state.set.clone(), 121 | state.drawable.getConstantState().newDrawable(), 122 | state.colorFilter); 123 | } 124 | 125 | return statesListDrawable; 126 | } 127 | 128 | @Override 129 | public int getChangingConfigurations() { 130 | return mConstantState.getChangingConfigurations(); 131 | } 132 | } 133 | } 134 | ``` 135 | -------------------------------------------------------------------------------- /gists/utils/uri.md: -------------------------------------------------------------------------------- 1 | ### Utils: Uri 2 | 3 | While working with file system we often need to get path from [Uri][1] object. 4 | 5 | As in Android 4.4 KitKat was added new Document picker we need to use 19 or later SDK version. 6 | 7 | In your manifest : 8 | 9 | ```xml 10 | 12 | ``` 13 | 14 | And here is `UriUtils` class : 15 | 16 | ```java 17 | public class UriUtils { 18 | 19 | public static String getPathFromUri(Context context, Uri uri) { 20 | String result = null; 21 | 22 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && 23 | DocumentsContract.isDocumentUri(context, uri)) { 24 | result = getPathFromDocumentURI(context, uri); 25 | } else if ("content".equalsIgnoreCase(uri.getScheme())) { 26 | result = getPathFromContentTypeUri(context, uri); 27 | } else if ("file".equalsIgnoreCase(uri.getScheme())) { 28 | result = uri.getPath(); 29 | } 30 | 31 | return result; 32 | } 33 | 34 | public static Uri getImageContentUri(Context context, File imageFile) { 35 | String filePath = imageFile.getAbsolutePath(); 36 | 37 | Cursor cursor = context.getContentResolver().query( 38 | MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 39 | new String[]{MediaStore.Images.Media._ID}, 40 | MediaStore.Images.Media.DATA + "=? ", 41 | new String[]{filePath}, null); 42 | if (cursor != null && cursor.moveToFirst()) { 43 | int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID)); 44 | return Uri.withAppendedPath( 45 | MediaStore.Images.Media.EXTERNAL_CONTENT_URI, Integer.toString(id) 46 | ); 47 | } else { 48 | if (imageFile.exists()) { 49 | ContentValues values = new ContentValues(); 50 | values.put(MediaStore.Images.Media.DATA, filePath); 51 | return context.getContentResolver().insert( 52 | MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); 53 | } else { 54 | return null; 55 | } 56 | } 57 | } 58 | 59 | private static String getPathFromContentTypeUri(Context context, Uri uri) { 60 | String result = null; 61 | Cursor cursor = null; 62 | 63 | try { 64 | cursor = context.getContentResolver().query(uri, null, null, null, null); 65 | int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA); 66 | if (cursor.moveToFirst()) { 67 | result = cursor.getString(columnIndex); 68 | } 69 | } catch (Exception e) { 70 | // Eat it 71 | e.printStackTrace(); 72 | } finally { 73 | if (cursor != null) { 74 | cursor.close(); 75 | } 76 | } 77 | 78 | return result; 79 | } 80 | 81 | private static String getPathFromDocumentURI(Context context, Uri uri) { 82 | String result = null; 83 | //Will return "image:x*" 84 | String wholeID = DocumentsContract.getDocumentId(uri); 85 | 86 | // Split at colon, use second item in the array 87 | String id = wholeID.split(":")[1]; 88 | 89 | String[] column = {MediaStore.Images.Media.DATA}; 90 | 91 | // where id is equal to 92 | String sel = MediaStore.Images.Media._ID + "=?"; 93 | Cursor cursor = null; 94 | try { 95 | cursor = context.getContentResolver().query( 96 | MediaStore.Images.Media.EXTERNAL_CONTENT_URI, 97 | column, 98 | sel, 99 | new String[]{id}, 100 | null); 101 | 102 | int columnIndex = cursor.getColumnIndex(column[0]); 103 | if (cursor.moveToFirst()) { 104 | result = cursor.getString(columnIndex); 105 | } 106 | } finally { 107 | if (cursor != null) { 108 | cursor.close(); 109 | } 110 | } 111 | return result; 112 | } 113 | } 114 | 115 | ``` 116 | 117 | 118 | [1]: http://developer.android.com/reference/android/net/Uri.html 119 | -------------------------------------------------------------------------------- /gists/sample/crop-photo.md: -------------------------------------------------------------------------------- 1 | Based on [UriUtils][1] 2 | 3 | ```java 4 | private static final int REQUEST_IMAGE_CAPTURE = 333; 5 | private static final int REQUEST_IMAGE_GET = 3331; 6 | private static final int REQUEST_IMAGE_CROP = 3332; 7 | 8 | //very important is to add extension to the saving file 9 | //this will prevent rotation bug on some samsung devices 10 | private static final String IMAGE_NAME = "capture.jpg"; 11 | private static final String CROPPED_IMAGE_NAME = "cropped_capture.jpg"; 12 | 13 | private Toast mToast; 14 | 15 | @Override 16 | protected void onActivityResult(int requestCode, int resultCode, Intent data) { 17 | super.onActivityResult(requestCode, resultCode, data); 18 | if (resultCode == RESULT_CANCELED) { 19 | return; 20 | } 21 | 22 | if (requestCode == REQUEST_IMAGE_CAPTURE) { 23 | File file = new File(getExternalCacheDir(), IMAGE_NAME); 24 | startCrop(Uri.fromFile(file)); 25 | } else if (requestCode == REQUEST_IMAGE_GET) { 26 | Uri uri = data.getData(); 27 | startCrop(Uri.fromFile(new File(UriUtils.getPathFromUri(getBaseContext(),uri)))); 28 | } else if (requestCode == REQUEST_IMAGE_CROP) { 29 | File file = new File(getExternalCacheDir(), CROPPED_IMAGE_NAME); 30 | //ViewerActivity.start(this, Uri.fromFile(file)); 31 | } 32 | } 33 | 34 | private void startGallery() { 35 | Intent intent = new Intent(Intent.ACTION_GET_CONTENT); 36 | intent.setType("image/*"); 37 | if (intent.resolveActivity(getPackageManager()) != null) { 38 | startActivityForResult(intent, REQUEST_IMAGE_GET); 39 | } else { 40 | showToast(R.string.Gallery_app_isnt_installed); 41 | } 42 | } 43 | 44 | private void startCamera() { 45 | File cacheDir = getExternalCacheDir(); 46 | if (cacheDir != null) { 47 | Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 48 | intent.putExtra( 49 | MediaStore.EXTRA_OUTPUT, 50 | Uri.withAppendedPath(Uri.fromFile(cacheDir), IMAGE_NAME) 51 | ); 52 | 53 | if (intent.resolveActivity(getPackageManager()) != null) { 54 | startActivityForResult(intent, REQUEST_IMAGE_CAPTURE); 55 | } else { 56 | showToast(R.string.Camera_app_isnt_installed); 57 | } 58 | } else { 59 | showToast(R.string.SD_is_unmounted); 60 | } 61 | } 62 | 63 | private void startCrop(@NonNull Uri uri) { 64 | File cacheDir = getExternalCacheDir(); 65 | if (cacheDir != null) { 66 | Intent intent = new Intent("com.android.camera.action.CROP"); 67 | intent.setDataAndType(uri, "image/*"); 68 | intent.putExtra("crop", true); 69 | intent.putExtra("noFaceDetectiona", true); 70 | intent.putExtra("return-data", false); 71 | intent.putExtra( 72 | MediaStore.EXTRA_OUTPUT, 73 | Uri.withAppendedPath(Uri.fromFile(cacheDir), CROPPED_IMAGE_NAME) 74 | ); 75 | if (intent.resolveActivity(getPackageManager()) != null) { 76 | startActivityForResult(intent, REQUEST_IMAGE_CROP); 77 | } else { 78 | //ViewerActivity.start(this, uri); 79 | } 80 | } else { 81 | showToast(R.string.SD_is_unmounted); 82 | } 83 | } 84 | 85 | private void showToast(int textId) { 86 | if (mToast == null) { 87 | mToast = Toast.makeText( 88 | getApplicationContext(), 89 | textId, 90 | Toast.LENGTH_LONG 91 | ); 92 | } 93 | 94 | if (!mToast.getView().isShown()) { 95 | mToast.show(); 96 | } else { 97 | mToast.setText(textId); 98 | } 99 | } 100 | ``` 101 | 102 | **strings.xml** 103 | ```xml 104 | SD is unmounted 105 | Gallery app isn\'t installed 106 | Camera app isn\'t installed 107 | ``` 108 | [1]: /gists/utils/uri.md 109 | -------------------------------------------------------------------------------- /gists/sample/activity-slide-animation.md: -------------------------------------------------------------------------------- 1 | **Usage** 2 | 3 | Extend `SlideAnimationActivity` and simply start/finish it. To change start animation of 3d party APPS 4 | 5 | ```java 6 | IntentUtils.openBrowser(activity, "github.com"); 7 | //start animation for 3d party app, we can just set in to on pause of fragment/activity, 8 | //but then this animation will start even after home press 9 | activity.overridePendingTransition(R.anim.pull_in_from_right, R.anim.hold); 10 | ``` 11 | 12 | To change close animation of 3d party APPS 13 | 14 | ```java 15 | @Override 16 | public void onStart() { 17 | super.onStart(); 18 | FragmentActivity activity = getActivity(); 19 | if(activity != null) { 20 | // start slide anim if fragment is resuming from browser or any 3d party app 21 | activity.overridePendingTransition(R.anim.pull_in_from_left, R.anim.pull_out_to_right); 22 | } 23 | } 24 | ``` 25 | 26 | **SlideAnimationActivity.class** 27 | 28 | ```java 29 | import android.content.Intent; 30 | import android.os.Bundle; 31 | import android.support.v4.app.NavUtils; 32 | import android.support.v4.app.TaskStackBuilder; 33 | import android.support.v7.app.ActionBarActivity; 34 | import android.view.MenuItem; 35 | 36 | public class SlideAnimationActivity extends ActionBarActivity { 37 | 38 | @Override 39 | protected void onCreate(Bundle savedInstanceState) { 40 | super.onCreate(savedInstanceState); 41 | overridePendingTransition(R.anim.pull_in_from_right, R.anim.hold); 42 | } 43 | 44 | @Override 45 | public boolean onOptionsItemSelected(MenuItem item) { 46 | switch (item.getItemId()) { 47 | case android.R.id.home: 48 | //Pressing back button in action bar doesn't call finish, 49 | //so we need to override Pending Transition here as well. 50 | //We can just set in to on pause, but then this animation will 51 | //start even after home press 52 | Intent upIntent = NavUtils.getParentActivityIntent(this); 53 | if (NavUtils.shouldUpRecreateTask(this, upIntent)) { 54 | TaskStackBuilder 55 | .create(this) 56 | .addNextIntentWithParentStack(upIntent) 57 | .startActivities() 58 | ; 59 | } else { 60 | NavUtils.navigateUpTo(this, upIntent); 61 | } 62 | overridePendingTransition(R.anim.pull_in_from_left, R.anim.pull_out_to_right); 63 | return true; 64 | } 65 | return super.onOptionsItemSelected(item); 66 | } 67 | 68 | @Override 69 | public void finish() { 70 | super.finish(); 71 | overridePendingTransition(R.anim.pull_in_from_left, R.anim.pull_out_to_right); 72 | } 73 | } 74 | ``` 75 | 76 | ============================== 77 | 78 | **res/anim/hold.xml** 79 | ```xml 80 | 81 | 85 | ``` 86 | 87 | **res/anim/pull_in_from_left.xml** 88 | ```xml 89 | 90 | 95 | ``` 96 | 97 | **res/anim/pull_in_from_right.xml** 98 | ```xml 99 | 100 | 105 | ``` 106 | 107 | **res/anim/pull_out_to_right.xml** 108 | ```xml 109 | 110 | 115 | ``` 116 | -------------------------------------------------------------------------------- /gists/gradle/build-files.md: -------------------------------------------------------------------------------- 1 | ### Gradle: Build files 2 | 3 | **main_build.gradle** 4 | ```java 5 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 6 | 7 | buildscript { 8 | repositories { 9 | mavenCentral() 10 | } 11 | dependencies { 12 | classpath 'com.android.tools.build:gradle:0.12.2' 13 | 14 | // NOTE: Do not place your application dependencies here; they belong 15 | // in the individual module build.gradle files 16 | } 17 | } 18 | 19 | allprojects { 20 | repositories { 21 | mavenCentral() 22 | } 23 | } 24 | ``` 25 | 26 | **settings.gradle** 27 | ```java 28 | include ':app', ':some-lib-project' 29 | 30 | project(':some-lib-project').projectDir = new File('../some-lib-project') 31 | ``` 32 | 33 | **app_build.gradle** 34 | ```java 35 | apply plugin: 'android' 36 | 37 | android { 38 | compileSdkVersion Integer.parseInt(project.COMPILE_SDK_VERSION) 39 | buildToolsVersion project.BUILD_TOOLS_VERSION 40 | 41 | defaultConfig { 42 | applicationId project.APP_PACKAGE 43 | minSdkVersion Integer.parseInt(project.MIN_SDK_VERSION) 44 | targetSdkVersion project.TARGET_SDK_VERSION 45 | } 46 | 47 | signingConfigs { 48 | 49 | release { 50 | storeFile file('.../release.keystore') 51 | keyAlias '..' 52 | keyPassword '..' 53 | storePassword '..' 54 | } 55 | 56 | flavor { 57 | storeFile file('.../flavor.keystore') 58 | keyAlias '..' 59 | keyPassword '..' 60 | storePassword '..' 61 | } 62 | } 63 | 64 | buildTypes { 65 | release { 66 | runProguard false 67 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 68 | signingConfig signingConfigs.release 69 | } 70 | } 71 | 72 | productFlavors { 73 | flavor{ 74 | applicationId project.FLAVOR_PACKAGE 75 | versionCode Integer.parseInt(project.VERSION_CODE) 76 | versionName project.VERSION_NAME 77 | signingConfig signingConfigs.flavor 78 | } 79 | } 80 | } 81 | 82 | dependencies { 83 | compile fileTree(dir: 'libs', include: ['*.jar']) 84 | compile 'org.jetbrains:annotations:13.0' 85 | compile 'com.android.support:appcompat-v7:20.0.0' 86 | compile 'com.google.android.gms:play-services:3.2.65' 87 | compile project(':some-lib-project') 88 | } 89 | ``` 90 | 91 | **gradle.properties** 92 | ```properties 93 | # Project-wide Gradle settings. 94 | 95 | # IDE (e.g. Android Studio) users: 96 | # Settings specified in this file will override any Gradle settings 97 | # configured through the IDE. 98 | 99 | # For more details on how to configure your build environment visit 100 | # http://www.gradle.org/docs/current/userguide/build_environment.html 101 | 102 | # Specifies the JVM arguments used for the daemon process. 103 | # The setting is particularly useful for tweaking memory settings. 104 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 105 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 106 | 107 | # When configured, Gradle will run in incubating parallel mode. 108 | # This option should only be used with decoupled projects. More details, visit 109 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 110 | # org.gradle.parallel=true 111 | 112 | #Common information 113 | 114 | COMPILE_SDK_VERSION=16 115 | BUILD_TOOLS_VERSION=20 116 | MIN_SDK_VERSION=8 117 | TARGET_SDK_VERSION=16 118 | APP_PACKAGE=app.package 119 | ``` 120 | 121 | **ant_project_build.gradle** 122 | ```java 123 | apply plugin: 'android-library' 124 | 125 | android { 126 | compileSdkVersion 16 127 | buildToolsVersion "20.0.0" 128 | 129 | sourceSets { 130 | main { 131 | manifest { 132 | srcFile 'AndroidManifest.xml' 133 | } 134 | java { 135 | srcDir 'src' 136 | } 137 | res { 138 | srcDir 'res' 139 | } 140 | assets { 141 | srcDir 'assets' 142 | } 143 | resources { 144 | srcDir 'src' 145 | } 146 | } 147 | } 148 | } 149 | ``` 150 | -------------------------------------------------------------------------------- /gists/model/async-data-loader.md: -------------------------------------------------------------------------------- 1 | ### Model: Async data loader 2 | 3 | Snippet shows simple implementation of download manager that : 4 | 5 | - Load data asynchronously 6 | - Cancel all request if some error occurs 7 | - Wait till all data will be downloaded 8 | - Save data if it was downloaded successfully 9 | 10 | #### When to use it? 11 | If you need to download some set of data that can be loaded asynchronously. And save it if all requests was successful 12 | 13 | #### Sources 14 | ```java 15 | public class DownloadManager { 16 | 17 | private int mQueuedRequests = 3; 18 | 19 | private Context mContext; 20 | private Callback mCallback; 21 | 22 | private Object mFirstResult; 23 | private List mSecondResult; 24 | private List mThirdResult; 25 | 26 | public void startLoading(@NotNull Context context, @NotNull Callback callback) { 27 | mContext = context; 28 | mCallback = callback; 29 | 30 | loadData(); 31 | } 32 | 33 | private void loadData() { 34 | loadFirstData(); 35 | loadSecondData(); 36 | //.. load all rest of data 37 | } 38 | 39 | private void loadFirstData() { 40 | HttpFactory.createFristRequest( 41 | new Response.Listener() { 42 | @Override 43 | public void onResponse(JSONObject jsonObject) { 44 | onFirstDataLoaded(jsonObject); 45 | checkLoadedData(); 46 | } 47 | }, errorListener 48 | ); 49 | } 50 | 51 | private void onFirstDataLoaded(JSONObject jsonObject) { 52 | mFirstResult = parseFirstData(jsonObject); 53 | } 54 | 55 | private void loadSecondData() { 56 | HttpFactory.createSecondRequest( 57 | new Response.Listener() { 58 | @Override 59 | public void onResponse(JSONObject jsonObject) { 60 | onSecondDataLoaded(jsonObject); 61 | checkLoadedData(); 62 | } 63 | }, errorListener 64 | ); 65 | } 66 | 67 | private void onSecondDataLoaded(JSONObject jsonObject) { 68 | mSecondResult = parseSecondData(jsonObject); 69 | } 70 | 71 | synchronized 72 | private void checkLoadedData() { 73 | if (--mQueuedRequests == 0) { 74 | saveData(); 75 | } 76 | } 77 | 78 | private void saveData() { 79 | if (mContext == null) { 80 | onUnexpectedBehavior("Context is null in saveData()"); 81 | } else if (isValidData()) { 82 | 83 | //save data here 84 | 85 | onDownloadSuccess(); 86 | } else { 87 | onDownloadError(); 88 | } 89 | } 90 | 91 | private boolean isValidData() { 92 | return mFirstResult != null 93 | && mSecondResult != null 94 | && mThirdResult != null; 95 | } 96 | 97 | private void onDownloadSuccess() { 98 | if (mCallback != null) { 99 | mCallback.onDownloadSuccess(); 100 | } 101 | } 102 | 103 | private void onDownloadError() { 104 | if (mCallback != null) { 105 | mCallback.onDownloadError(); 106 | } 107 | } 108 | 109 | private void onUnexpectedBehavior(String reason) { 110 | if (mCallback != null) { 111 | mCallback.onUnexpectedBehavior(reason); 112 | } 113 | } 114 | 115 | private boolean mIsCanceled; 116 | private Response.ErrorListener errorListener = new Response.ErrorListener() { 117 | @Override 118 | public void onErrorResponse(VolleyError volleyError) { 119 | L.e(volleyError.getMessage()); 120 | if (!mIsCanceled) { 121 | mIsCanceled = true; 122 | onDownloadError(); 123 | RequestManager.queue().cancelAll(new RequestQueue.RequestFilter() { 124 | @Override 125 | public boolean apply(Request request) { 126 | return true; 127 | } 128 | }); 129 | } 130 | } 131 | }; 132 | 133 | public static abstract class Callback { 134 | 135 | abstract public void onDownloadSuccess(); 136 | 137 | abstract public void onDownloadError(); 138 | 139 | public void onUnexpectedBehavior(String reason) { 140 | L.e(reason); 141 | } 142 | } 143 | } 144 | ``` 145 | -------------------------------------------------------------------------------- /gists/view/vertical-view-pager/VerticalBaseTransformer.java: -------------------------------------------------------------------------------- 1 | package com.stacy.planets.controller.view; 2 | 3 | import android.support.v4.view.ViewPager; 4 | import android.view.View; 5 | 6 | /** 7 | * Created by T530 on 18/09/2014. 8 | */ 9 | public abstract class VerticalBaseTransformer implements ViewPager.PageTransformer { 10 | /** 11 | * Called each {@link #transformPage(android.view.View, float)}. 12 | * 13 | * @param page Apply the transformation to this page 14 | * @param position Position of page relative to the current front-and-center position of the pager. 0 is front and 15 | * center. 1 is one full page position to the right, and -1 is one page position to the left. 16 | */ 17 | protected abstract void onTransform(View page, float position); 18 | 19 | /** 20 | * Apply a property transformation to the given page. For most use cases, this method should not be overridden. 21 | * Instead use {@link #transformPage(android.view.View, float)} to perform typical transformations. 22 | * 23 | * @param page Apply the transformation to this page 24 | * @param position Position of page relative to the current front-and-center position of the pager. 0 is front and 25 | * center. 1 is one full page position to the right, and -1 is one page position to the left. 26 | */ 27 | @Override 28 | public void transformPage(View page, float position) { 29 | onPreTransform(page, position); 30 | onTransform(page, position); 31 | onPostTransform(page, position); 32 | } 33 | 34 | /** 35 | * If the position offset of a fragment is less than negative one or greater than one, returning true will set the 36 | * fragment alpha to 0f. Otherwise fragment alpha is always defaulted to 1f. 37 | * 38 | * @return 39 | */ 40 | protected boolean hideOffscreenPages() { 41 | return true; 42 | } 43 | 44 | /** 45 | * Indicates if the default animations of the view pager should be used. 46 | * 47 | * @return 48 | */ 49 | protected boolean isPagingEnabled() { 50 | return false; 51 | } 52 | 53 | /** 54 | * Called each {@link #transformPage(android.view.View, float)} before {{@link #onTransform(android.view.View, float)}. 55 | *

56 | * The default implementation attempts to reset all view properties. This is useful when toggling transforms that do 57 | * not modify the same page properties. For instance changing from a transformation that applies rotation to a 58 | * transformation that fades can inadvertently leave a fragment stuck with a rotation or with some degree of applied 59 | * alpha. 60 | * 61 | * @param page Apply the transformation to this page 62 | * @param position Position of page relative to the current front-and-center position of the pager. 0 is front and 63 | * center. 1 is one full page position to the right, and -1 is one page position to the left. 64 | */ 65 | protected void onPreTransform(View page, float position) { 66 | final float width = page.getWidth(); 67 | final float height = page.getHeight(); 68 | 69 | page.setRotationX(0); 70 | page.setRotationY(0); 71 | page.setRotation(0); 72 | page.setScaleX(1); 73 | page.setScaleY(1); 74 | page.setPivotX(0); 75 | page.setPivotY(0); 76 | page.setTranslationX(0); 77 | page.setTranslationY(isPagingEnabled() ? 0f : -height * position); 78 | 79 | if (hideOffscreenPages()) { 80 | page.setAlpha(position <= -1f || position >= 1f ? 0f : 1f); 81 | } else { 82 | page.setAlpha(1f); 83 | } 84 | 85 | /*final float normalizedposition = Math.abs(Math.abs(position) - 1); 86 | page.setAlpha(normalizedposition);*/ 87 | } 88 | 89 | /** 90 | * Called each {@link #transformPage(android.view.View, float)} after {@link #onTransform(android.view.View, float)}. 91 | * 92 | * @param page Apply the transformation to this page 93 | * @param position Position of page relative to the current front-and-center position of the pager. 0 is front and 94 | * center. 1 is one full page position to the right, and -1 is one page position to the left. 95 | */ 96 | protected void onPostTransform(View page, float position) { 97 | } 98 | 99 | /** 100 | * Same as {@link Math#min(double, double)} without double casting, zero closest to infinity handling, or NaN support. 101 | * 102 | * @param val 103 | * @param min 104 | * @return 105 | */ 106 | protected static final float min(float val, float min) { 107 | return val < min ? min : val; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /gists/view/activity-toast-factory.md: -------------------------------------------------------------------------------- 1 | ### Utils: ToastFactory 2 | Sample shows simple factory that creates [ActivityToast][1]'s 3 | 4 | #### Usage 5 | ```java 6 | ToastFactory.makeText(this, ActivityToast.LENGTH_LONG, mOnClickListener).show(); 7 | ``` 8 | 9 | #### Sources 10 | 11 | ```java 12 | import android.app.Activity; 13 | import android.view.View; 14 | import android.view.ViewGroup; 15 | 16 | public class ToastFactory { 17 | 18 | public static ActivityToast makeText( 19 | Activity activity, long length, View.OnClickListener listener) { 20 | 21 | final View view = activity.getLayoutInflater().inflate( 22 | R.layout.view_toast, 23 | (ViewGroup) activity.getWindow().getDecorView(), 24 | false 25 | ); 26 | view.findViewById(R.id.btnAction).setOnClickListener(listener); 27 | 28 | final ActivityToast toast = new ActivityToast(activity, view); 29 | toast.setLength(length); 30 | return toast; 31 | } 32 | 33 | } 34 | 35 | ``` 36 | 37 | #### Resources 38 | 39 | **view_toast.xml** file 40 | ```xml 41 | 42 | 49 | 50 | 65 | 66 | 75 | 76 | 77 |