Skip to content

Instantly share code, notes, and snippets.

@gorodechnyj
Created April 19, 2016 14:44
Show Gist options
  • Save gorodechnyj/bbfb881c0f9934d28c3eebbcac45bfb6 to your computer and use it in GitHub Desktop.
Save gorodechnyj/bbfb881c0f9934d28c3eebbcac45bfb6 to your computer and use it in GitHub Desktop.
Skeleton classes of my applications
package ch.dotpay.skeleton.activity;
import android.Manifest;
import android.animation.Animator;
import android.app.Dialog;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.transition.TransitionInflater;
import android.util.Log;
import android.view.View;
import ch.dotpay.DotpayApplication;
import ch.dotpay.R;
import ch.dotpay.core.shared.ProviderWrapper;
import ch.dotpay.network.api.ApiFactory;
import ch.dotpay.network.model.ServerError;
import ch.dotpay.ui.fragment.GenericFragment;
import ch.dotpay.utils.AlertUtils;
import ch.dotpay.utils.GMSUtils;
/**
* Created by gorodechnyj on 18.01.16.
*/
public class BaseActivity extends AppCompatActivity {
private static final int REQUEST_LOCATION_PERMISSION = 4;
private Handler handler = new Handler();
private boolean mPaused = false;
private View mProgressView;
private Dialog mCurrentDialog;
protected ProviderWrapper providerWrapper;
protected DotpayApplication dotpayApplication;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dotpayApplication = ((DotpayApplication) getApplication());
providerWrapper = dotpayApplication.getProviderWrapper();
}
public void addFragment(final int containerResId, final Fragment fragment, final boolean addToBackStack) {
handler.post(new Runnable() {
@Override
public void run() {
if (!mPaused) {
final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.add(containerResId, fragment, fragment.getClass().getName());
if (addToBackStack) {
ft.addToBackStack(fragment.getClass().getName());
}
ft.commitAllowingStateLoss();
}
}
});
}
public void replaceFragment(final int containerResId, final Fragment fragment, final boolean addToBackStack) {
replaceFragment(containerResId, fragment, addToBackStack, false);
}
public void replaceFragment(final int containerResId, final Fragment fragment, final boolean addToBackStack, final boolean animate) {
handler.post(new Runnable() {
@Override
public void run() {
if (!mPaused) {
final FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(containerResId, fragment, fragment.getClass().getName());
if (animate) {
if (Build.VERSION.SDK_INT >= 21) {
fragment.setEnterTransition(TransitionInflater.from(BaseActivity.this)
.inflateTransition(android.R.transition.slide_right));
fragment.setExitTransition(TransitionInflater.from(BaseActivity.this)
.inflateTransition(android.R.transition.fade));
} else {
ft.setCustomAnimations(R.anim.slide_left_in, R.anim.slide_left_out, R.anim.slide_right_in, R.anim.slide_right_out);
}
}
if (addToBackStack) {
ft.addToBackStack(fragment.getClass().getName());
}
ft.commitAllowingStateLoss();
}
}
});
}
@Override
protected void onResume() {
super.onResume();
if (GMSUtils.checkLocationPermission(this, REQUEST_LOCATION_PERMISSION)) {
dismissAlert();
GMSUtils.checkGeolocationEnabled(this);
}
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mProgressView = findViewById(R.id.progressView);
}
@Override
protected void onDestroy() {
super.onDestroy();
mPaused = true;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == GMSUtils.GMS_REQUEST_GEO_LOCATION &&
!GMSUtils.isGeolocationEnabled(this)) {
finish();
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == REQUEST_LOCATION_PERMISSION) {
if (grantResults.length == 0
|| grantResults[0] != PackageManager.PERMISSION_GRANTED) {
if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
showAlert(AlertUtils.getAskPermissionDialog(BaseActivity.this,
getString(R.string.permissionRequired),
getString(R.string.locationPermissionRequired),
REQUEST_LOCATION_PERMISSION));
}
}
return;
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
/**
* Throbber, if used, shown above the any widgets and blocks user actions.
*/
public void showThrobber() {
if (mProgressView != null && !mPaused) {
mProgressView.animate()
.alpha(1f)
.setDuration(200)
.setListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
mProgressView.setVisibility(View.VISIBLE);
}
@Override
public void onAnimationEnd(Animator animation) {
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
}
}
public void hideThrobber() {
if (mProgressView != null && !mPaused) {
mProgressView.animate()
.alpha(0f)
.setDuration(200)
.setListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
}
@Override
public void onAnimationEnd(Animator animation) {
mProgressView.setVisibility(View.GONE);
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
}
}
public boolean isThrobberShown() {
return mProgressView != null && mProgressView.getVisibility() == View.VISIBLE;
}
public View getThrobber() {
return mProgressView;
}
public void showAlert(Dialog dialog) {
dismissAlert();
mCurrentDialog = dialog;
mCurrentDialog.show();
}
public void dismissAlert() {
if (mCurrentDialog != null) {
mCurrentDialog.dismiss();
mCurrentDialog = null;
}
}
}
package ch.dotpay.skeleton.binding;
import android.content.Context;
import android.databinding.BindingAdapter;
import android.graphics.Typeface;
import android.support.design.widget.TextInputLayout;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Pair;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import java.util.HashMap;
import ch.dotpay.R;
import ch.dotpay.skeleton.util.CircleTransformation;
/**
* Created by Belozerow on 11.10.2015.
*/
public class BindingAttributes {
private static HashMap<String, Typeface> typefaceHashMap = new HashMap<>();
@BindingAdapter({"bind:circleUrl"})
public static void setCircleUrl(ImageView imageView, String url) {
if (url == null)
return;
Picasso.with(imageView.getContext()).load(url).transform(new CircleTransformation()).into(imageView);
}
@BindingAdapter({"bind:imageUrl"})
public static void setImageUrl(ImageView imageView, String url) {
if (url == null)
return;
Picasso.with(imageView.getContext()).load(url).into(imageView);
}
@BindingAdapter("bind:typeface")
public static void setTypeface(TextView textView, String font) {
Typeface tf = typefaceHashMap.get(font);
if (tf == null) {
tf = Typeface.createFromAsset(textView.getContext().getAssets(), "fonts/" + font);
typefaceHashMap.put(font, tf);
}
textView.setTypeface(tf);
}
@BindingAdapter({"bind:imageRes"})
public static void setImageRes(ImageView imageView, int res) {
imageView.setImageResource(res);
}
@BindingAdapter({"bind:imageResName"})
public static void setImageResName(ImageView imageView, String resName) {
Context context = imageView.getContext();
if (TextUtils.isEmpty(resName)) {
return;
}
int id = context.getResources().getIdentifier(resName, "drawable", context.getPackageName());
imageView.setImageResource(id);
}
@BindingAdapter({"bind:twoWayText"})
public static void bindEditText(EditText view,
final ObservableString observableString) {
Pair<ObservableString, TextWatcher> pair =
(Pair) view.getTag(R.id.bound_observable);
if (pair == null || pair.first != observableString) {
if (pair != null) {
view.removeTextChangedListener(pair.second);
}
TextWatcher watcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s,
int start, int before, int count) {
observableString.set(s.toString());
}
@Override
public void afterTextChanged(Editable s) {
}
};
view.setTag(R.id.bound_observable,
new Pair<>(observableString, watcher));
view.addTextChangedListener(watcher);
}
if (observableString != null) {
String newValue = observableString.get();
if (!view.getText().toString().equals(newValue)) {
view.setText(newValue);
}
}
if (view.getParent() != null
&& view.getParent() instanceof TextInputLayout) {
((TextInputLayout) view.getParent()).refreshDrawableState();
}
}
// @BindingAdapter("app:swipeEnabled")
// public static void setLayoutWidth(SwipeLayout view, boolean enabled) {
// view.setSwipeEnabled(enabled);
// }
// @BindingAdapter({"app:twoWayBoolean"})
// public static void bindCheckBox(CheckBox view, final ObservableBoolean observableBoolean) {
// if (observableBoolean != null) {
// if (view.getTag(R.id.bound_observable) != observableBoolean) {
// view.setTag(R.id.bound_observable, observableBoolean);
// view.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
// @Override
// public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
// observableBoolean.set(isChecked);
// }
// });
// }
// boolean newValue = observableBoolean.get();
// if (view.isChecked() != newValue) {
// view.setChecked(newValue);
// }
// }
// }
//
// @BindingAdapter({"app:twoWaySpinner"})
// public static void bindSpinner(final Spinner spinner, final ObservableString observable) {
// if (observable != null) {
// if (spinner.getTag(R.id.bound_observable) != observable) {
// spinner.setTag(R.id.bound_observable, observable);
// spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
// @Override
// public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
// observable.set((String) spinner.getItemAtPosition(position));
// }
//
// @Override
// public void onNothingSelected(AdapterView<?> parent) {
//
// }
// });
// }
// String newValue = observable.get();
// if (newValue == null)
// return;
// if (!observable.equals(spinner.getSelectedItem())) {
// SpinnerAdapter spinnerAdapter = spinner.getAdapter();
// int selectedItem = spinner.getSelectedItemPosition();
// if (spinnerAdapter != null) {
// for (int i = 0; i < spinnerAdapter.getCount(); i++) {
// if (newValue.equals(spinnerAdapter.getItem(i))) {
// selectedItem = i;
// break;
// }
// }
// }
// spinner.setSelection(selectedItem);
// }
//
// }
// }
// @BindingAdapter({"android:entries"})
// public static void setFriendsSpinner(Spinner spinner, ArrayList<Friend> items) {
// ArrayList<String> strings = new ArrayList<>();
// for (Friend item : items) {
// strings.add(item.userName.get());
// }
// ArrayAdapter<String> adapter = new ArrayAdapter<>(spinner.getContext(), R.layout.item_friends_spinner, strings);
// spinner.setAdapter(adapter);
// }
@BindingAdapter({"bind:error"})
public static void setTextInputError(TextInputLayout textInputLayout, String error) {
if (TextUtils.isEmpty(error)) {
textInputLayout.setError(null);
} else {
textInputLayout.setError(error);
}
}
@BindingAdapter({"bind:error"})
public static void setTextInputError(TextInputLayout textInputLayout, int errorResId) {
if (errorResId == 0) {
textInputLayout.setError(null);
} else {
textInputLayout.setError(textInputLayout.getContext().getResources().getString(errorResId));
}
}
@BindingAdapter({"bind:onActionDone"})
public static void setOnDoneListener(EditText editText, TextView.OnEditorActionListener listener) {
editText.setOnEditorActionListener(listener);
}
@BindingAdapter({"bind:onLongClick"})
public static void setOnLongClickListener(View view, View.OnLongClickListener listener) {
view.setOnLongClickListener(listener);
}
@BindingAdapter({"bind:onItemLongClick"})
public static void setOnLongClickListener(AdapterView view, AdapterView.OnItemLongClickListener listener) {
view.setOnItemLongClickListener(listener);
}
@BindingAdapter({"app:onItemClick"})
public static void setOnItemClickListener(AdapterView view, AdapterView.OnItemClickListener listener) {
view.setOnItemClickListener(listener);
}
@BindingAdapter({"app:visibility"})
public static void setVisibility(View view, boolean isVisible) {
view.setVisibility(isVisible ? View.VISIBLE : View.GONE);
}
}
package ch.dotpay.skeleton.binding;
import android.databinding.ViewDataBinding;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Created by Belozerow on 29.11.2015.
*/
public class DataBindingUtils {
public static ViewDataBinding getViewDataBinding(Class clazz, LayoutInflater inflater, ViewGroup container) {
Method method = null;
try {
method = clazz.getMethod("inflate", LayoutInflater.class, ViewGroup.class, boolean.class);
return (ViewDataBinding) method.invoke(null, inflater, container, false);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
}
package ch.dotpay.skeleton.binding;
import android.databinding.BaseObservable;
import android.databinding.BindingConversion;
import android.os.Parcel;
import android.os.Parcelable;
import java.io.Serializable;
/**
* Created: Belozerov
* Company: APPGRANULA LLC
* Date: 15.01.2016
*/
public class ObservableString extends BaseObservable implements Parcelable, Serializable {
static final long serialVersionUID = 1L;
private String mValue;
public static final Creator<ObservableString> CREATOR = new Creator<ObservableString>() {
public ObservableString createFromParcel(Parcel source) {
return new ObservableString(source.readString());
}
public ObservableString[] newArray(int size) {
return new ObservableString[size];
}
};
public ObservableString(String value) {
this.mValue = value;
}
public ObservableString() {
}
public String get() {
return this.mValue;
}
public void set(String value) {
if (!equals(value, this.mValue)) {
this.mValue = value;
this.notifyChange();
}
}
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.mValue);
}
public boolean isEmpty() {
return mValue == null || mValue.isEmpty();
}
@BindingConversion
public static String convertToString(ObservableString s) {
return s.get();
}
}
package ch.dotpay.skeleton.fragment;
import android.databinding.ViewDataBinding;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import ch.dotpay.DotpayApplication;
import ch.dotpay.R;
import ch.dotpay.core.FragmentLauncher;
import ch.dotpay.core.shared.ProviderWrapper;
import ch.dotpay.pref.UserPref;
import ch.dotpay.skeleton.activity.BaseActivity;
import ch.dotpay.skeleton.binding.DataBindingUtils;
/**
* Created: gorodechnyj
* Date: 27.03.2016
*/
public abstract class BaseFragment<T extends ViewDataBinding> extends Fragment {
private final Class<T> typeParameterClass;
protected T binding;
public static final String ADD_TO_BACK_STACK = "add_to_back_stack";
public abstract String getTitle();
protected DotpayApplication dotpayApplication;
protected ProviderWrapper providerWrapper;
protected UserPref userPref;
protected ActionBar actionBar;
public BaseFragment(Class<T> typeParameterClass) {
super();
this.typeParameterClass = typeParameterClass;
}
public String getFragmentTag() {
Class<?> enclosingClass = getClass().getEnclosingClass();
if (enclosingClass != null) {
return enclosingClass.getName();
} else {
return getClass().getName();
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dotpayApplication = ((DotpayApplication) getActivity().getApplication());
providerWrapper = dotpayApplication.getProviderWrapper();
userPref = UserPref.with(getActivity());
setHasOptionsMenu(true);
}
public BaseActivity getBaseActivity() {
return (BaseActivity) getActivity();
}
private boolean isBackStack() {
return getArguments().getBoolean(ADD_TO_BACK_STACK);
}
@Override
public void onResume() {
super.onResume();
setTitle(getTitle());
}
protected void setTitle(String title) {
if (actionBar != null)
actionBar.setTitle(title);
}
protected ActionBar getSupportActionBar() {
return ((AppCompatActivity) getActivity()).getSupportActionBar();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
getFragmentManager().popBackStack();
return true;
}
return super.onOptionsItemSelected(item);
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
binding = (T) DataBindingUtils.getViewDataBinding(typeParameterClass, inflater, container);
View view = binding.getRoot();
Toolbar toolbar = (Toolbar) view.findViewById(R.id.toolbar);
if (toolbar != null) {
getBaseActivity().setSupportActionBar(toolbar);
}
actionBar = getSupportActionBar();
return view;
}
public boolean onBackPressed() {
return false;
}
}
package ch.dotpay.skeleton.util;
import android.graphics.Bitmap;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import com.squareup.picasso.Transformation;
public class CircleTransformation implements Transformation {
@Override
public Bitmap transform(Bitmap source) {
int size = Math.min(source.getWidth(), source.getHeight());
int x = (source.getWidth() - size) / 2;
int y = (source.getHeight() - size) / 2;
Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size);
if (squaredBitmap != source) {
source.recycle();
}
Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig());
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
BitmapShader shader = new BitmapShader(squaredBitmap, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
paint.setShader(shader);
paint.setAntiAlias(true);
float r = size / 2f;
canvas.drawCircle(r, r, r, paint);
squaredBitmap.recycle();
return bitmap;
}
@Override
public String key() {
return "circle";
}
}
package ch.dotpay.skeleton.widget;
/*
* Copyright (C) 2014 skyfish.jy@gmail.com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import android.content.Context;
import android.database.Cursor;
import android.database.DataSetObserver;
import android.support.v7.widget.RecyclerView;
/**
* Created by skyfishjy on 10/31/14.
*/
public abstract class CursorRecyclerViewAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> {
protected Context mContext;
private Cursor mCursor;
private boolean mDataValid;
private int mRowIdColumn;
private DataSetObserver mDataSetObserver;
public CursorRecyclerViewAdapter(Context context, Cursor cursor) {
mContext = context;
mCursor = cursor;
mDataValid = cursor != null;
mRowIdColumn = mDataValid ? mCursor.getColumnIndex("_id") : -1;
mDataSetObserver = new NotifyingDataSetObserver();
if (mCursor != null) {
mCursor.registerDataSetObserver(mDataSetObserver);
}
}
public Cursor getCursor() {
return mCursor;
}
@Override
public int getItemCount() {
if (mDataValid && mCursor != null) {
return mCursor.getCount();
}
return 0;
}
@Override
public long getItemId(int position) {
if (mDataValid && mCursor != null && mCursor.moveToPosition(position)) {
return mCursor.getLong(mRowIdColumn);
}
return 0;
}
@Override
public void setHasStableIds(boolean hasStableIds) {
super.setHasStableIds(true);
}
public abstract void onBindViewHolder(VH viewHolder, Cursor cursor, int position);
@Override
public void onBindViewHolder(VH viewHolder, int position) {
if (!mDataValid) {
throw new IllegalStateException("this should only be called when the cursor is valid");
}
if (!mCursor.moveToPosition(position)) {
throw new IllegalStateException("couldn't move cursor to position " + position);
}
onBindViewHolder(viewHolder, mCursor, position);
}
/**
* Change the underlying cursor to a new cursor. If there is an existing cursor it will be
* closed.
*/
public void changeCursor(Cursor cursor) {
Cursor old = swapCursor(cursor);
if (old != null) {
old.close();
}
}
/**
* Swap in a new Cursor, returning the old Cursor. Unlike
* {@link #changeCursor(Cursor)}, the returned old Cursor is <em>not</em>
* closed.
*/
public Cursor swapCursor(Cursor newCursor) {
if (newCursor == mCursor) {
return null;
}
final Cursor oldCursor = mCursor;
if (oldCursor != null && mDataSetObserver != null) {
oldCursor.unregisterDataSetObserver(mDataSetObserver);
}
mCursor = newCursor;
if (mCursor != null) {
if (mDataSetObserver != null) {
mCursor.registerDataSetObserver(mDataSetObserver);
}
mRowIdColumn = newCursor.getColumnIndexOrThrow("_id");
mDataValid = true;
notifyDataSetChanged();
} else {
mRowIdColumn = -1;
mDataValid = false;
notifyDataSetChanged();
//There is no notifyDataSetInvalidated() method in RecyclerView.Adapter
}
return oldCursor;
}
private class NotifyingDataSetObserver extends DataSetObserver {
@Override
public void onChanged() {
super.onChanged();
mDataValid = true;
notifyDataSetChanged();
}
@Override
public void onInvalidated() {
super.onInvalidated();
mDataValid = false;
notifyDataSetChanged();
//There is no notifyDataSetInvalidated() method in RecyclerView.Adapter
}
}
}
package ch.dotpay.skeleton.widget;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.view.WindowInsets;
import android.widget.FrameLayout;
/**
* @author Kevin
* Date Created: 3/7/14
* <p/>
* https://code.google.com/p/android/issues/detail?id=63777
* <p/>
* When using a translucent status bar on API 19+, the window will not
* resize to make room for input methods (i.e.
* {@link android.view.WindowManager.LayoutParams#SOFT_INPUT_ADJUST_RESIZE} and
* {@link android.view.WindowManager.LayoutParams#SOFT_INPUT_ADJUST_PAN} are
* ignored).
* <p/>
* To work around this; override {@link #fitSystemWindows(android.graphics.Rect)},
* capture and override the system insets, and then call through to LinearLayout's
* implementation.
* <p/>
* For reasons yet unknown, modifying the bottom inset causes this workaround to
* fail. Modifying the top, left, and right insets works as expected.
*/
public final class CustomInsetsFrameLayout extends FrameLayout {
private int[] mInsets = new int[4];
public CustomInsetsFrameLayout(Context context) {
super(context);
}
public CustomInsetsFrameLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomInsetsFrameLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public final int[] getInsets() {
return mInsets;
}
@Override
public final WindowInsets onApplyWindowInsets(WindowInsets insets) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
mInsets[0] = insets.getSystemWindowInsetLeft();
mInsets[1] = insets.getSystemWindowInsetTop();
mInsets[2] = insets.getSystemWindowInsetRight();
return super.onApplyWindowInsets(insets.replaceSystemWindowInsets(0, 0, 0,
insets.getSystemWindowInsetBottom()));
} else {
return insets;
}
}
}
package ch.dotpay.skeleton.widget;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.view.WindowInsets;
import android.widget.LinearLayout;
/**
* @author Kevin
* Date Created: 3/7/14
* <p/>
* https://code.google.com/p/android/issues/detail?id=63777
* <p/>
* When using a translucent status bar on API 19+, the window will not
* resize to make room for input methods (i.e.
* {@link android.view.WindowManager.LayoutParams#SOFT_INPUT_ADJUST_RESIZE} and
* {@link android.view.WindowManager.LayoutParams#SOFT_INPUT_ADJUST_PAN} are
* ignored).
* <p/>
* To work around this; override {@link #fitSystemWindows(android.graphics.Rect)},
* capture and override the system insets, and then call through to LinearLayout's
* implementation.
* <p/>
* For reasons yet unknown, modifying the bottom inset causes this workaround to
* fail. Modifying the top, left, and right insets works as expected.
*/
public final class CustomInsetsLinearLayout extends LinearLayout {
private int[] mInsets = new int[4];
public CustomInsetsLinearLayout(Context context) {
super(context);
}
public CustomInsetsLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CustomInsetsLinearLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public final int[] getInsets() {
return mInsets;
}
@Override
public final WindowInsets onApplyWindowInsets(WindowInsets insets) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
mInsets[0] = insets.getSystemWindowInsetLeft();
mInsets[1] = insets.getSystemWindowInsetTop();
mInsets[2] = insets.getSystemWindowInsetRight();
return super.onApplyWindowInsets(insets.replaceSystemWindowInsets(0, 0, 0,
insets.getSystemWindowInsetBottom()));
} else {
return insets;
}
}
}
package ch.dotpay.skeleton.widget;
import android.support.v7.widget.RecyclerView;
/**
* Created by gorodechnyj on 30.03.2016.
*/
public abstract class ItemClickableRecyclerViewAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> {
@Override
public void onBindViewHolder(VH holder, int position) {
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment